Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package spicetify-cli for openSUSE:Factory 
checked in at 2025-02-12 21:38:41
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/spicetify-cli (Old)
 and      /work/SRC/openSUSE:Factory/.spicetify-cli.new.8181 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "spicetify-cli"

Wed Feb 12 21:38:41 2025 rev:7 rq:1245367 version:2.39.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/spicetify-cli/spicetify-cli.changes      
2025-02-04 19:34:58.407604038 +0100
+++ /work/SRC/openSUSE:Factory/.spicetify-cli.new.8181/spicetify-cli.changes    
2025-02-12 21:40:12.371694828 +0100
@@ -1,0 +2,17 @@
+Wed Feb 12 11:11:17 UTC 2025 - jan.kuzi...@suse.com
+
+- Update to version 2.39.2:
+  * fix(preprocess): remove checking spotify ver
+  * chore(lyrics-plus/OptionsMenu): change displayed text
+  * fix: re-render lyrics div when `Translation Display` is changed
+  * feat(lyrics-plus): allow to change display of lyrics translation (#3297)
+  * feat(lyrics-plus): add select language translation for Musixmatch provider 
(#3288)
+  * feat: patch only `xpui.js` on Spotify `1.2.57` and higher
+  * fix(homeConfig): make the regex work on more versions
+  * feat(wrapper): add smooth scrolling for Spotify 1.2.56
+  * fix(expFeatures): make it work on versions without `RemoteConfigDebugAPI`
+  * feat: migrate state folders
+  * chore(deps): bump github.com/mattn/go-colorable from 0.1.13 to 0.1.14 
(#3267)
+  * chore(deps): bump golang.org/x/net from 0.33.0 to 0.34.0 (#3265)
+
+-------------------------------------------------------------------

Old:
----
  cli-2.38.9.obscpio

New:
----
  cli-2.39.2.obscpio

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ spicetify-cli.spec ++++++
--- /var/tmp/diff_new_pack.Z6SKsf/_old  2025-02-12 21:40:12.903716756 +0100
+++ /var/tmp/diff_new_pack.Z6SKsf/_new  2025-02-12 21:40:12.903716756 +0100
@@ -19,7 +19,7 @@
 %define sname cli
 %define binname spicetify
 Name:           spicetify-cli
-Version:        2.38.9
+Version:        2.39.2
 Release:        0
 Summary:        Command-line tool to customize Spotify client
 License:        LGPL-2.1-or-later

++++++ _service ++++++
--- /var/tmp/diff_new_pack.Z6SKsf/_old  2025-02-12 21:40:12.931717911 +0100
+++ /var/tmp/diff_new_pack.Z6SKsf/_new  2025-02-12 21:40:12.935718075 +0100
@@ -3,7 +3,7 @@
     <param name="url">https://github.com/spicetify/cli</param>
     <param name="scm">git</param>
     <param name="exclude">.git</param>
-    <param name="revision">v2.38.9</param>
+    <param name="revision">v2.39.2</param>
     <param name="versionformat">@PARENT_TAG@</param>
     <param name="changesgenerate">enable</param>
     <param name="versionrewrite-pattern">v(.*)</param>

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.Z6SKsf/_old  2025-02-12 21:40:12.955718900 +0100
+++ /var/tmp/diff_new_pack.Z6SKsf/_new  2025-02-12 21:40:12.955718900 +0100
@@ -1,6 +1,6 @@
 <servicedata>
 <service name="tar_scm">
                 <param name="url">https://github.com/spicetify/cli</param>
-              <param 
name="changesrevision">77455ba174dca0bb839546f52c9e4690a27a1b64</param></service></servicedata>
+              <param 
name="changesrevision">c3485db5542b4527fff84039c0286f00e2ed6316</param></service></servicedata>
 (No newline at EOF)
 

++++++ cli-2.38.9.obscpio -> cli-2.39.2.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cli-2.38.9/CustomApps/lyrics-plus/OptionsMenu.js 
new/cli-2.39.2/CustomApps/lyrics-plus/OptionsMenu.js
--- old/cli-2.38.9/CustomApps/lyrics-plus/OptionsMenu.js        2025-02-03 
20:54:41.000000000 +0100
+++ new/cli-2.39.2/CustomApps/lyrics-plus/OptionsMenu.js        2025-02-08 
15:52:56.000000000 +0100
@@ -92,6 +92,13 @@
                        none: "None",
                };
 
+               const savedTranslationDisplay = 
localStorage.getItem(`${APP_NAME}:visual:translate:display-mode`) || "replace";
+               CONFIG.visual["translate:display-mode"] = 
savedTranslationDisplay;
+               const translationDisplayOptions = {
+                       replace: "Replace original",
+                       below: "Below original",
+               };
+
                const languageOptions = {
                        off: "Off",
                        "zh-hans": "Chinese (Simplified)",
@@ -100,12 +107,18 @@
                        ko: "Korean",
                };
 
-               let modeOptions = {};
+               let modeOptions = {
+                       none: "None",
+               };
 
                if (hasTranslation.musixmatch) {
+                       const selectedLanguage = 
CONFIG.visual["musixmatch-translation-language"];
+                       const languageName = new 
Intl.DisplayNames([selectedLanguage], {
+                               type: "language",
+                       }).of(selectedLanguage);
                        sourceOptions = {
                                ...sourceOptions,
-                               musixmatchTranslation: "English (Musixmatch)",
+                               musixmatchTranslation: `${languageName} 
(Musixmatch)`,
                        };
                }
 
@@ -152,6 +165,19 @@
                                renderInline: true,
                        },
                        {
+                               desc: "Translation Display",
+                               key: "translate:display-mode",
+                               type: ConfigSelection,
+                               onChange: (name, value) => {
+                                       CONFIG.visual[name] = value;
+                                       
localStorage.setItem(`${APP_NAME}:visual:${name}`, value);
+                                       lyricContainerUpdate?.();
+                               },
+                               options: translationDisplayOptions,
+                               defaultValue: savedTranslationDisplay,
+                               renderInline: true,
+                       },
+                       {
                                desc: "Language Override",
                                key: "translate:detect-language-override",
                                type: ConfigSelection,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cli-2.38.9/CustomApps/lyrics-plus/Pages.js 
new/cli-2.39.2/CustomApps/lyrics-plus/Pages.js
--- old/cli-2.38.9/CustomApps/lyrics-plus/Pages.js      2025-02-03 
20:54:41.000000000 +0100
+++ new/cli-2.39.2/CustomApps/lyrics-plus/Pages.js      2025-02-08 
15:52:56.000000000 +0100
@@ -140,7 +140,7 @@
                                },
                                key: lyricsId,
                        },
-                       activeLines.map(({ text, lineNumber, startTime }, i) => 
{
+                       activeLines.map(({ text, lineNumber, startTime, 
originalText }, i) => {
                                if (i === 1 && activeLineIndex === 1) {
                                        return 
react.createElement(IdlingIndicator, {
                                                progress: position / 
activeLines[2].startTime,
@@ -169,33 +169,68 @@
                                if (paddingLine) {
                                        className += " 
lyrics-lyricsContainer-LyricsLine-paddingLine";
                                }
+                               const showTranslatedBelow = 
CONFIG.visual["translate:display-mode"] === "below";
+                               // If we have original text and we are showing 
translated below, we should show the original text
+                               // Otherwise we should show the translated text
+                               const lineText = originalText && 
showTranslatedBelow ? originalText : text;
 
                                return react.createElement(
-                                       "p",
+                                       "div",
                                        {
-                                               className,
-                                               style: {
-                                                       cursor: "pointer",
-                                                       "--position-index": 
animationIndex,
-                                                       "--animation-index": 
(animationIndex < 0 ? 0 : animationIndex) + 1,
-                                                       "--blur-index": 
Math.abs(animationIndex),
-                                               },
-                                               key: lineNumber,
-                                               dir: "auto",
-                                               ref,
-                                               onClick: (event) => {
-                                                       if (startTime) {
-                                                               
Spicetify.Player.seek(startTime);
-                                                       }
-                                               },
-                                               onContextMenu: (event) => {
-                                                       event.preventDefault();
-                                                       
Spicetify.Platform.ClipboardAPI.copy(rawLyrics)
-                                                               .then(() => 
Spicetify.showNotification("Lyrics copied to clipboard"))
-                                                               .catch(() => 
Spicetify.showNotification("Failed to copy lyrics to clipboard"));
-                                               },
+                                               className: 
"lyrics-lyricsContainer-LyricsLineContainer",
+                                               key: i,
                                        },
-                                       !isKara ? text : 
react.createElement(KaraokeLine, { text, startTime, position, isActive })
+                                       react.createElement(
+                                               "p",
+                                               {
+                                                       className,
+                                                       style: {
+                                                               cursor: 
"pointer",
+                                                               
"--position-index": animationIndex,
+                                                               
"--animation-index": (animationIndex < 0 ? 0 : animationIndex) + 1,
+                                                               "--blur-index": 
Math.abs(animationIndex),
+                                                       },
+                                                       key: lineNumber,
+                                                       dir: "auto",
+                                                       ref,
+                                                       onClick: (event) => {
+                                                               if (startTime) {
+                                                                       
Spicetify.Player.seek(startTime);
+                                                               }
+                                                       },
+                                                       onContextMenu: (event) 
=> {
+                                                               
event.preventDefault();
+                                                               
Spicetify.Platform.ClipboardAPI.copy(rawLyrics)
+                                                                       
.then(() => Spicetify.showNotification("Lyrics copied to clipboard"))
+                                                                       
.catch(() => Spicetify.showNotification("Failed to copy lyrics to clipboard"));
+                                                       },
+                                               },
+                                               !isKara ? lineText : 
react.createElement(KaraokeLine, { text, startTime, position, isActive })
+                                       ),
+                                       showTranslatedBelow &&
+                                               originalText &&
+                                               originalText !== text &&
+                                               react.createElement(
+                                                       "p",
+                                                       {
+                                                               className,
+                                                               style: {
+                                                                       
opacity: 0.5,
+                                                                       cursor: 
"pointer",
+                                                                       
"--position-index": animationIndex,
+                                                                       
"--animation-index": (animationIndex < 0 ? 0 : animationIndex) + 1,
+                                                                       
"--blur-index": Math.abs(animationIndex),
+                                                               },
+                                                               dir: "auto",
+                                                               ref,
+                                                               onClick: 
(event) => {
+                                                                       if 
(startTime) {
+                                                                               
Spicetify.Player.seek(startTime);
+                                                                       }
+                                                               },
+                                                       },
+                                                       text
+                                               )
                                );
                        })
                ),
@@ -412,7 +447,7 @@
                react.createElement("p", {
                        className: 
"lyrics-lyricsContainer-LyricsUnsyncedPadding",
                }),
-               padded.map(({ text, startTime }, i) => {
+               padded.map(({ text, startTime, originalText }, i) => {
                        if (i === 0) {
                                return react.createElement(IdlingIndicator, {
                                        isActive: activeLineIndex === 0,
@@ -422,28 +457,57 @@
                        }
 
                        const isActive = i === activeLineIndex;
+                       const showTranslatedBelow = 
CONFIG.visual["translate:display-mode"] === "below";
+                       // If we have original text and we are showing 
translated below, we should show the original text
+                       // Otherwise we should show the translated text
+                       const lineText = originalText && showTranslatedBelow ? 
originalText : text;
                        return react.createElement(
-                               "p",
+                               "div",
                                {
-                                       className: 
`lyrics-lyricsContainer-LyricsLine${i <= activeLineIndex ? " 
lyrics-lyricsContainer-LyricsLine-active" : ""}`,
-                                       style: {
-                                               cursor: "pointer",
-                                       },
-                                       dir: "auto",
-                                       ref: isActive ? activeLineRef : null,
-                                       onClick: (event) => {
-                                               if (startTime) {
-                                                       
Spicetify.Player.seek(startTime);
-                                               }
-                                       },
-                                       onContextMenu: (event) => {
-                                               event.preventDefault();
-                                               
Spicetify.Platform.ClipboardAPI.copy(rawLyrics)
-                                                       .then(() => 
Spicetify.showNotification("Lyrics copied to clipboard"))
-                                                       .catch(() => 
Spicetify.showNotification("Failed to copy lyrics to clipboard"));
-                                       },
+                                       className: 
"lyrics-lyricsContainer-LyricsLineContainer",
+                                       key: i,
                                },
-                               !isKara ? text : 
react.createElement(KaraokeLine, { text, startTime, position, isActive })
+                               react.createElement(
+                                       "p",
+                                       {
+                                               className: 
`lyrics-lyricsContainer-LyricsLine${i <= activeLineIndex ? " 
lyrics-lyricsContainer-LyricsLine-active" : ""}`,
+                                               style: {
+                                                       cursor: "pointer",
+                                               },
+                                               dir: "auto",
+                                               ref: isActive ? activeLineRef : 
null,
+                                               onClick: (event) => {
+                                                       if (startTime) {
+                                                               
Spicetify.Player.seek(startTime);
+                                                       }
+                                               },
+                                               onContextMenu: (event) => {
+                                                       event.preventDefault();
+                                                       
Spicetify.Platform.ClipboardAPI.copy(rawLyrics)
+                                                               .then(() => 
Spicetify.showNotification("Lyrics copied to clipboard"))
+                                                               .catch(() => 
Spicetify.showNotification("Failed to copy lyrics to clipboard"));
+                                               },
+                                       },
+                                       !isKara ? lineText : 
react.createElement(KaraokeLine, { text, startTime, position, isActive })
+                               ),
+                               showTranslatedBelow &&
+                                       originalText &&
+                                       originalText !== text &&
+                                       react.createElement(
+                                               "p",
+                                               {
+                                                       className: 
`lyrics-lyricsContainer-LyricsLine${i <= activeLineIndex ? " 
lyrics-lyricsContainer-LyricsLine-active" : ""}`,
+                                                       style: { opacity: 0.5, 
cursor: "pointer" },
+                                                       dir: "auto",
+                                                       ref: isActive ? 
activeLineRef : null,
+                                                       onClick: (event) => {
+                                                               if (startTime) {
+                                                                       
Spicetify.Player.seek(startTime);
+                                                               }
+                                                       },
+                                               },
+                                               text
+                                       )
                        );
                }),
                react.createElement("p", {
@@ -468,20 +532,44 @@
                react.createElement("p", {
                        className: 
"lyrics-lyricsContainer-LyricsUnsyncedPadding",
                }),
-               lyrics.map(({ text }) => {
+               lyrics.map(({ text, originalText }, index) => {
+                       const showTranslatedBelow = 
CONFIG.visual["translate:display-mode"] === "below";
+                       // If we have original text and we are showing 
translated below, we should show the original text
+                       // Otherwise we should show the translated text
+                       const lineText = originalText && showTranslatedBelow ? 
originalText : text;
+
                        return react.createElement(
-                               "p",
+                               "div",
                                {
-                                       className: 
"lyrics-lyricsContainer-LyricsLine lyrics-lyricsContainer-LyricsLine-active",
-                                       dir: "auto",
-                                       onContextMenu: (event) => {
-                                               event.preventDefault();
-                                               
Spicetify.Platform.ClipboardAPI.copy(rawLyrics)
-                                                       .then(() => 
Spicetify.showNotification("Lyrics copied to clipboard"))
-                                                       .catch(() => 
Spicetify.showNotification("Failed to copy lyrics to clipboard"));
-                                       },
+                                       className: 
"lyrics-lyricsContainer-LyricsLineContainer",
+                                       key: index,
                                },
-                               text
+                               react.createElement(
+                                       "p",
+                                       {
+                                               className: 
"lyrics-lyricsContainer-LyricsLine lyrics-lyricsContainer-LyricsLine-active",
+                                               dir: "auto",
+                                               onContextMenu: (event) => {
+                                                       event.preventDefault();
+                                                       
Spicetify.Platform.ClipboardAPI.copy(rawLyrics)
+                                                               .then(() => 
Spicetify.showNotification("Lyrics copied to clipboard"))
+                                                               .catch(() => 
Spicetify.showNotification("Failed to copy lyrics to clipboard"));
+                                               },
+                                       },
+                                       lineText
+                               ),
+                               showTranslatedBelow &&
+                                       originalText &&
+                                       originalText !== text &&
+                                       react.createElement(
+                                               "p",
+                                               {
+                                                       className: 
"lyrics-lyricsContainer-LyricsLine lyrics-lyricsContainer-LyricsLine-active",
+                                                       style: { opacity: 0.5 },
+                                                       dir: "auto",
+                                               },
+                                               text
+                                       )
                        );
                }),
                react.createElement("p", {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/cli-2.38.9/CustomApps/lyrics-plus/ProviderMusixmatch.js 
new/cli-2.39.2/CustomApps/lyrics-plus/ProviderMusixmatch.js
--- old/cli-2.38.9/CustomApps/lyrics-plus/ProviderMusixmatch.js 2025-02-03 
20:54:41.000000000 +0100
+++ new/cli-2.39.2/CustomApps/lyrics-plus/ProviderMusixmatch.js 2025-02-08 
15:52:56.000000000 +0100
@@ -162,11 +162,15 @@
                const track_id = 
body?.["matcher.track.get"]?.message?.body?.track?.track_id;
                if (!track_id) return null;
 
+               const selectedLanguage = 
CONFIG.visual["musixmatch-translation-language"] || "none";
+               if (selectedLanguage === "none") return null;
+
                const baseURL =
-                       
"https://apic-desktop.musixmatch.com/ws/1.1/crowd.track.translations.get?translation_fields_set=minimal&selected_language=en&comment_format=text&format=json&app_id=web-desktop-app-v1.0&";;
+                       
"https://apic-desktop.musixmatch.com/ws/1.1/crowd.track.translations.get?translation_fields_set=minimal&comment_format=text&format=json&app_id=web-desktop-app-v1.0&";;
 
                const params = {
                        track_id,
+                       selected_language: selectedLanguage,
                        usertoken: CONFIG.providers.musixmatch.token,
                };
 
@@ -184,7 +188,10 @@
 
                if (!result.translations_list?.length) return null;
 
-               return result.translations_list.map(({ translation }) => ({ 
translation: translation.description, matchedLine: translation.matched_line }));
+               return result.translations_list.map(({ translation }) => ({
+                       translation: translation.description,
+                       matchedLine: translation.matched_line,
+               }));
        }
 
        return { findLyrics, getKaraoke, getSynced, getUnsynced, getTranslation 
};
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cli-2.38.9/CustomApps/lyrics-plus/Settings.js 
new/cli-2.39.2/CustomApps/lyrics-plus/Settings.js
--- old/cli-2.38.9/CustomApps/lyrics-plus/Settings.js   2025-02-03 
20:54:41.000000000 +0100
+++ new/cli-2.39.2/CustomApps/lyrics-plus/Settings.js   2025-02-08 
15:52:56.000000000 +0100
@@ -512,6 +512,19 @@
                );
        });
 };
+const languageCodes =
+       
"none,en,af,ar,bg,bn,ca,zh,cs,da,de,el,es,et,fa,fi,fr,gu,he,hi,hr,hu,id,is,it,ja,jv,kn,ko,lt,lv,ml,mr,ms,nl,no,pl,pt,ro,ru,sk,sl,sr,su,sv,ta,te,th,tr,uk,ur,vi,zu".split(
+               ","
+       );
+
+const displayNames = new Intl.DisplayNames(["en"], { type: "language" });
+const languageOptions = languageCodes.reduce((acc, code) => {
+       acc[code] = code === "none" ? "None" : displayNames.of(code);
+       return acc;
+}, {});
+
+const savedLanguage = 
localStorage.getItem(`${APP_NAME}:visual:musixmatch-translation-language`) || 
"none";
+CONFIG.visual["musixmatch-translation-language"] = savedLanguage;
 
 function openConfig() {
        const configContainer = react.createElement(
@@ -630,6 +643,14 @@
                                        max: thresholdSizeLimit.max,
                                        step: thresholdSizeLimit.step,
                                },
+                               {
+                                       desc: "Musixmatch Translation 
Language.",
+                                       info: "Choose the language you want to 
translate the lyrics to. Changes will take effect after the next track.",
+                                       key: "musixmatch-translation-language",
+                                       type: ConfigSelection,
+                                       options: languageOptions,
+                                       defaultValue: savedLanguage,
+                               },
                        ],
                        onChange: (name, value) => {
                                CONFIG.visual[name] = value;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cli-2.38.9/CustomApps/lyrics-plus/index.js 
new/cli-2.39.2/CustomApps/lyrics-plus/index.js
--- old/cli-2.38.9/CustomApps/lyrics-plus/index.js      2025-02-03 
20:54:41.000000000 +0100
+++ new/cli-2.39.2/CustomApps/lyrics-plus/index.js      2025-02-08 
15:52:56.000000000 +0100
@@ -41,6 +41,7 @@
                "lines-after": 
localStorage.getItem("lyrics-plus:visual:lines-after") || "2",
                "font-size": 
localStorage.getItem("lyrics-plus:visual:font-size") || "32",
                "translate:translated-lyrics-source": 
localStorage.getItem("lyrics-plus:visual:translate:translated-lyrics-source") 
|| "none",
+               "translate:display-mode": 
localStorage.getItem("lyrics-plus:visual:translate:display-mode") || "replace",
                "translate:detect-language-override": 
localStorage.getItem("lyrics-plus:visual:translate:detect-language-override") 
|| "off",
                "translation-mode:japanese": 
localStorage.getItem("lyrics-plus:visual:translation-mode:japanese") || 
"furigana",
                "translation-mode:korean": 
localStorage.getItem("lyrics-plus:visual:translation-mode:korean") || "hangul",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cli-2.38.9/go.mod new/cli-2.39.2/go.mod
--- old/cli-2.38.9/go.mod       2025-02-03 20:54:41.000000000 +0100
+++ new/cli-2.39.2/go.mod       2025-02-08 15:52:56.000000000 +0100
@@ -4,12 +4,12 @@
 
 require (
        github.com/go-ini/ini v1.67.0
-       github.com/mattn/go-colorable v0.1.13
-       golang.org/x/net v0.33.0
+       github.com/mattn/go-colorable v0.1.14
+       golang.org/x/net v0.34.0
 )
 
 require (
-       github.com/mattn/go-isatty v0.0.16 // indirect
+       github.com/mattn/go-isatty v0.0.20 // indirect
        github.com/stretchr/testify v1.7.1 // indirect
-       golang.org/x/sys v0.28.0 // indirect
+       golang.org/x/sys v0.29.0 // indirect
 )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cli-2.38.9/go.sum new/cli-2.39.2/go.sum
--- old/cli-2.38.9/go.sum       2025-02-03 20:54:41.000000000 +0100
+++ new/cli-2.39.2/go.sum       2025-02-08 15:52:56.000000000 +0100
@@ -2,20 +2,20 @@
 github.com/davecgh/go-spew v1.1.0/go.mod 
h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=
 github.com/go-ini/ini v1.67.0/go.mod 
h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
-github.com/mattn/go-colorable v0.1.13 
h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
-github.com/mattn/go-colorable v0.1.13/go.mod 
h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
-github.com/mattn/go-isatty v0.0.16 
h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
-github.com/mattn/go-isatty v0.0.16/go.mod 
h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
+github.com/mattn/go-colorable v0.1.14 
h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
+github.com/mattn/go-colorable v0.1.14/go.mod 
h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
+github.com/mattn/go-isatty v0.0.20 
h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
+github.com/mattn/go-isatty v0.0.20/go.mod 
h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
 github.com/pmezard/go-difflib v1.0.0 
h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod 
h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/stretchr/objx v0.1.0/go.mod 
h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/testify v1.7.1 
h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
 github.com/stretchr/testify v1.7.1/go.mod 
h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
-golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
-golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
-golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
+golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
+golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod 
h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c 
h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod 
h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cli-2.38.9/jsHelper/expFeatures.js 
new/cli-2.39.2/jsHelper/expFeatures.js
--- old/cli-2.38.9/jsHelper/expFeatures.js      2025-02-03 20:54:41.000000000 
+0100
+++ new/cli-2.39.2/jsHelper/expFeatures.js      2025-02-08 15:52:56.000000000 
+0100
@@ -166,7 +166,8 @@
                        }
                        isFallback = false;
                        notice.remove();
-                       remoteConfiguration = 
Spicetify?.RemoteConfigResolver?.remoteConfiguration ?? (await 
Spicetify.Platform?.RemoteConfigDebugAPI.getProperties());
+                       remoteConfiguration =
+                               
Spicetify?.RemoteConfigResolver?.value.remoteConfiguration ?? (await 
Spicetify.Platform?.RemoteConfigDebugAPI.getProperties());
                })();
 
                for (const key of Object.keys(overrideList)) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cli-2.38.9/jsHelper/spicetifyWrapper.js 
new/cli-2.39.2/jsHelper/spicetifyWrapper.js
--- old/cli-2.38.9/jsHelper/spicetifyWrapper.js 2025-02-03 20:54:41.000000000 
+0100
+++ new/cli-2.39.2/jsHelper/spicetifyWrapper.js 2025-02-08 15:52:56.000000000 
+0100
@@ -306,6 +306,51 @@
        Platform: {},
 };
 
+// Based on 
https://blog.aziz.tn/2025/01/spotify-fix-lagging-issue-on-scrolling.html
+function applyScrollingFix() {
+       const scrollableElements = 
Array.from(document.querySelectorAll("*")).filter((el) => {
+               if (
+                       el.id === "context-menu" ||
+                       el.closest("#context-menu") ||
+                       el.getAttribute("role") === "dialog" ||
+                       el.classList.contains("popup") ||
+                       el.getAttribute("aria-haspopup") === "true"
+               )
+                       return false;
+
+               const style = window.getComputedStyle(el);
+               return style.overflow === "auto" || style.overflow === "scroll" 
|| style.overflowY === "auto" || style.overflowY === "scroll";
+       });
+
+       for (const el of scrollableElements) {
+               if (!el.hasAttribute("data-scroll-optimized")) {
+                       el.style.willChange = "transform";
+                       el.style.transform = "translate3d(0, 0, 0)";
+                       el.setAttribute("data-scroll-optimized", "true");
+               }
+       }
+}
+
+const observer = new MutationObserver(applyScrollingFix);
+
+observer.observe(document.body, {
+       childList: true,
+       subtree: true,
+       attributes: false,
+});
+
+const originalPushState = history.pushState;
+history.pushState = function (...args) {
+       originalPushState.apply(this, args);
+       setTimeout(applyScrollingFix, 100);
+};
+
+window.addEventListener("popstate", () => {
+       setTimeout(applyScrollingFix, 100);
+});
+
+applyScrollingFix();
+
 (function waitForPlatform() {
        if (!Spicetify._platform) {
                setTimeout(waitForPlatform, 50);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cli-2.38.9/spicetify.go new/cli-2.39.2/spicetify.go
--- old/cli-2.38.9/spicetify.go 2025-02-03 20:54:41.000000000 +0100
+++ new/cli-2.39.2/spicetify.go 2025-02-08 15:52:56.000000000 +0100
@@ -111,6 +111,7 @@
        }
 
        utils.MigrateConfigFolder()
+       utils.MigrateFolders()
        cmd.InitConfig(quiet)
 
        if len(commands) < 1 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cli-2.38.9/src/apply/apply.go 
new/cli-2.39.2/src/apply/apply.go
--- old/cli-2.38.9/src/apply/apply.go   2025-02-03 20:54:41.000000000 +0100
+++ new/cli-2.39.2/src/apply/apply.go   2025-02-08 15:52:56.000000000 +0100
@@ -4,6 +4,7 @@
        "fmt"
        "os"
        "path/filepath"
+       "strconv"
        "strings"
 
        "github.com/spicetify/cli/src/utils"
@@ -36,9 +37,6 @@
                        insertSidebarConfig,
                        insertHomeConfig,
                },
-               filepath.Join(appsFolderPath, "xpui", "vendor~xpui.js"): {
-                       insertExpFeatures,
-               },
                filepath.Join(appsFolderPath, "xpui", "home-v2.js"): {
                        insertHomeConfig,
                },
@@ -47,6 +45,24 @@
                },
        }
 
+       verParts := strings.Split(flags.SpotifyVer, ".")
+       spotifyMajor, spotifyMinor, spotifyPatch := 0, 0, 0
+       if len(verParts) > 0 {
+               spotifyMajor, _ = strconv.Atoi(verParts[0])
+       }
+       if len(verParts) > 1 {
+               spotifyMinor, _ = strconv.Atoi(verParts[1])
+       }
+       if len(verParts) > 2 {
+               spotifyPatch, _ = strconv.Atoi(verParts[2])
+       }
+
+       if spotifyMajor >= 1 && spotifyMinor >= 2 && spotifyPatch >= 57 {
+               filesToModified[filepath.Join(appsFolderPath, "xpui", 
"xpui.js")] = append(filesToModified[filepath.Join(appsFolderPath, "xpui", 
"xpui.js")], insertExpFeatures)
+       } else {
+               filesToModified[filepath.Join(appsFolderPath, "xpui", 
"vendor~xpui.js")] = []func(string, Flag){insertExpFeatures}
+       }
+
        for file, calls := range filesToModified {
                if _, err := os.Stat(file); os.IsNotExist(err) {
                        continue
@@ -361,10 +377,10 @@
                                return 
fmt.Sprintf("%sSpicetifyHomeConfig.arrange(%s)%s", submatches[1], 
submatches[2], submatches[3])
                        })
 
-               // >= 1.2.45
+               // >= 1.2.40
                utils.ReplaceOnce(
                        &content,
-                       `(&&"HomeShortsSectionData".*\],)([a-zA-Z])(\}\)\()`,
+                       
`(&&"HomeShortsSectionData".*?[\],}])([a-zA-Z])(\}\)?\()`,
                        func(submatches ...string) string {
                                return 
fmt.Sprintf("%sSpicetifyHomeConfig.arrange(%s)%s", submatches[1], 
submatches[2], submatches[3])
                        })
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cli-2.38.9/src/cmd/backup.go 
new/cli-2.39.2/src/cmd/backup.go
--- old/cli-2.38.9/src/cmd/backup.go    2025-02-03 20:54:41.000000000 +0100
+++ new/cli-2.39.2/src/cmd/backup.go    2025-02-08 15:52:56.000000000 +0100
@@ -72,7 +72,8 @@
                        DisableSentry:  
preprocSection.Key("disable_sentry").MustBool(false),
                        DisableLogging: 
preprocSection.Key("disable_ui_logging").MustBool(false),
                        RemoveRTL:      
preprocSection.Key("remove_rtl_rule").MustBool(false),
-                       ExposeAPIs:     
preprocSection.Key("expose_apis").MustBool(false)},
+                       ExposeAPIs:     
preprocSection.Key("expose_apis").MustBool(false),
+                       SpotifyVer:     utils.GetSpotifyVersion(prefsPath)},
        )
        utils.PrintGreen("OK")
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cli-2.38.9/src/preprocess/preprocess.go 
new/cli-2.39.2/src/preprocess/preprocess.go
--- old/cli-2.38.9/src/preprocess/preprocess.go 2025-02-03 20:54:41.000000000 
+0100
+++ new/cli-2.39.2/src/preprocess/preprocess.go 2025-02-08 15:52:56.000000000 
+0100
@@ -26,6 +26,7 @@
        RemoveRTL bool
        // ExposeAPIs leaks some Spotify's API, functions, objects to Spicetify 
global object.
        ExposeAPIs bool
+       SpotifyVer string
 }
 
 func readRemoteCssMap(tag string, cssTranslationMap *map[string]string) error {
@@ -82,6 +83,18 @@
                readLocalCssMap(&cssTranslationMap)
        }
 
+       verParts := strings.Split(flags.SpotifyVer, ".")
+       spotifyMajor, spotifyMinor, spotifyPatch := 0, 0, 0
+       if len(verParts) > 0 {
+               spotifyMajor, _ = strconv.Atoi(verParts[0])
+       }
+       if len(verParts) > 1 {
+               spotifyMinor, _ = strconv.Atoi(verParts[1])
+       }
+       if len(verParts) > 2 {
+               spotifyPatch, _ = strconv.Atoi(verParts[2])
+       }
+
        filepath.Walk(appPath, func(path string, info os.FileInfo, err error) 
error {
                fileName := info.Name()
                extension := filepath.Ext(fileName)
@@ -101,6 +114,9 @@
                                        switch fileName {
                                        case "xpui.js":
                                                content = 
exposeAPIs_main(content)
+                                               if spotifyMajor >= 1 && 
spotifyMinor >= 2 && spotifyPatch >= 57 {
+                                                       content = 
exposeAPIs_vendor(content)
+                                               }
                                        case "vendor~xpui.js":
                                                content = 
exposeAPIs_vendor(content)
                                        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cli-2.38.9/src/utils/path-utils.go 
new/cli-2.39.2/src/utils/path-utils.go
--- old/cli-2.38.9/src/utils/path-utils.go      2025-02-03 20:54:41.000000000 
+0100
+++ new/cli-2.39.2/src/utils/path-utils.go      2025-02-08 15:52:56.000000000 
+0100
@@ -24,6 +24,52 @@
        }
 }
 
+func MigrateFolders() {
+       backupPath := filepath.Join(GetSpicetifyFolder(), "Backup")
+       extractedPath := filepath.Join(GetSpicetifyFolder(), "Extracted")
+
+       if _, err := os.Stat(backupPath); err == nil {
+               newBackupPath := GetStateFolder("Backup")
+               oldAbs, err := filepath.Abs(backupPath)
+               if err != nil {
+                       Fatal(err)
+               }
+               newAbs, err := filepath.Abs(newBackupPath)
+               if err != nil {
+                       Fatal(err)
+               }
+
+               if oldAbs != newAbs {
+                       PrintBold("Migrating spicetify state (Backup, 
Extracted) folders")
+                       err := Copy(backupPath, newBackupPath, true, nil)
+                       if err != nil {
+                               Fatal(err)
+                       }
+                       os.RemoveAll(backupPath)
+               }
+       }
+
+       if _, err := os.Stat(extractedPath); err == nil {
+               newExtractedPath := GetStateFolder("Extracted")
+               oldAbs, err := filepath.Abs(extractedPath)
+               if err != nil {
+                       Fatal(err)
+               }
+               newAbs, err := filepath.Abs(newExtractedPath)
+               if err != nil {
+                       Fatal(err)
+               }
+               if oldAbs != newAbs {
+                       PrintBold("Migrating spicetify state (Backup, 
Extracted) folders")
+                       err := Copy(extractedPath, newExtractedPath, true, nil)
+                       if err != nil {
+                               Fatal(err)
+                       }
+                       os.RemoveAll(extractedPath)
+               }
+       }
+}
+
 func ReplaceEnvVarsInString(input string) string {
        var replacements []string
        for _, v := range os.Environ() {

++++++ cli.obsinfo ++++++
--- /var/tmp/diff_new_pack.Z6SKsf/_old  2025-02-12 21:40:13.143726649 +0100
+++ /var/tmp/diff_new_pack.Z6SKsf/_new  2025-02-12 21:40:13.143726649 +0100
@@ -1,5 +1,5 @@
 name: cli
-version: 2.38.9
-mtime: 1738612481
-commit: 77455ba174dca0bb839546f52c9e4690a27a1b64
+version: 2.39.2
+mtime: 1739026376
+commit: c3485db5542b4527fff84039c0286f00e2ed6316
 

++++++ vendor.tar.gz ++++++
++++ 24531 lines of diff (skipped)

Reply via email to