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-03-13 15:07:58
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/spicetify-cli (Old)
 and      /work/SRC/openSUSE:Factory/.spicetify-cli.new.19136 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "spicetify-cli"

Thu Mar 13 15:07:58 2025 rev:9 rq:1252741 version:2.39.5

Changes:
--------
--- /work/SRC/openSUSE:Factory/spicetify-cli/spicetify-cli.changes      
2025-02-16 22:50:20.796594975 +0100
+++ /work/SRC/openSUSE:Factory/.spicetify-cli.new.19136/spicetify-cli.changes   
2025-03-13 15:08:40.348428866 +0100
@@ -1,0 +2,14 @@
+Thu Mar 13 11:23:58 UTC 2025 - jan.kuzi...@suse.com
+
+- Update to version 2.39.5:
+  * fix: remove bypass flag after checking for admin
+  * fix(popupLyrics): update view in system tray mode (#3330)
+  * feat(types): add `dark_vibrant` to `colorExtractor` (#3321)
+  * feat(popupLyrics): implement lyrics caching & Musixmatch token refresh 
(#3328)
+  * style: run `fmt` on `isAdmin` pkg
+  * fix: split `isAdmin` to platform files
+  * fix(preprocess): add css for height on apps pages (1.2.57+)
+  * feat: disallow running spicetify as admin/root
+  * fix(lyrics-plus): properly set height on main view (#3322)
+
+-------------------------------------------------------------------

Old:
----
  cli-2.39.3.obscpio

New:
----
  cli-2.39.5.obscpio

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

Other differences:
------------------
++++++ spicetify-cli.spec ++++++
--- /var/tmp/diff_new_pack.uK3rm8/_old  2025-03-13 15:08:41.996497994 +0100
+++ /var/tmp/diff_new_pack.uK3rm8/_new  2025-03-13 15:08:42.004498330 +0100
@@ -19,7 +19,7 @@
 %define sname cli
 %define binname spicetify
 Name:           spicetify-cli
-Version:        2.39.3
+Version:        2.39.5
 Release:        0
 Summary:        Command-line tool to customize Spotify client
 License:        LGPL-2.1-or-later

++++++ _service ++++++
--- /var/tmp/diff_new_pack.uK3rm8/_old  2025-03-13 15:08:42.244508398 +0100
+++ /var/tmp/diff_new_pack.uK3rm8/_new  2025-03-13 15:08:42.264509236 +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.39.3</param>
+    <param name="revision">v2.39.5</param>
     <param name="versionformat">@PARENT_TAG@</param>
     <param name="changesgenerate">enable</param>
     <param name="versionrewrite-pattern">v(.*)</param>

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.uK3rm8/_old  2025-03-13 15:08:42.420515780 +0100
+++ /var/tmp/diff_new_pack.uK3rm8/_new  2025-03-13 15:08:42.460517458 +0100
@@ -1,6 +1,6 @@
 <servicedata>
 <service name="tar_scm">
                 <param name="url">https://github.com/spicetify/cli</param>
-              <param 
name="changesrevision">0414d766239b51f1d6cff6802c9fb361e4a64fe4</param></service></servicedata>
+              <param 
name="changesrevision">c99cdf6673e1a81a64a426117538b19c042e4f3e</param></service></servicedata>
 (No newline at EOF)
 

++++++ cli-2.39.3.obscpio -> cli-2.39.5.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cli-2.39.3/CustomApps/lyrics-plus/index.js 
new/cli-2.39.5/CustomApps/lyrics-plus/index.js
--- old/cli-2.39.3/CustomApps/lyrics-plus/index.js      2025-02-14 
18:20:05.000000000 +0100
+++ new/cli-2.39.5/CustomApps/lyrics-plus/index.js      2025-03-01 
00:22:37.000000000 +0100
@@ -58,9 +58,14 @@
                delay: 0,
        },
        providers: {
+               lrclib: {
+                       on: getConfig("lyrics-plus:provider:lrclib:on"),
+                       desc: "Lyrics sourced from lrclib.net. Supports both 
synced and unsynced lyrics. LRCLIB is a free and open-source lyrics provider.",
+                       modes: [SYNCED, UNSYNCED],
+               },
                musixmatch: {
                        on: getConfig("lyrics-plus:provider:musixmatch:on"),
-                       desc: "Fully compatible with Spotify. Requires a token 
that can be retrieved from the official Musixmatch app. If you have problems 
with retrieving lyrics, try refreshing the token by clicking <code>Refresh 
Token</code> button.",
+                       desc: "Fully compatible with Spotify. Requires a token 
that can be retrieved from the official Musixmatch app. If you have problems 
with retrieving lyrics, try refreshing the token by clicking <code>Refresh 
Token</code> button. You may need to be forced to use your own CORS Proxy to 
use this provider.",
                        token: 
localStorage.getItem("lyrics-plus:provider:musixmatch:token") || 
"21051986b9886beabe1ce01c3ce94c96319411f8f2c122676365e3",
                        modes: [KARAOKE, SYNCED, UNSYNCED],
                },
@@ -70,15 +75,10 @@
                        modes: [SYNCED, UNSYNCED],
                },
                netease: {
-                       on: getConfig("lyrics-plus:provider:netease:on"),
+                       on: getConfig("lyrics-plus:provider:netease:on", false),
                        desc: "Crowdsourced lyrics provider ran by Chinese 
developers and users.",
                        modes: [KARAOKE, SYNCED, UNSYNCED],
                },
-               lrclib: {
-                       on: getConfig("lyrics-plus:provider:lrclib:on"),
-                       desc: "Lyrics sourced from lrclib.net. Supports both 
synced and unsynced lyrics. LRCLIB is a free and open-source lyrics provider.",
-                       modes: [SYNCED, UNSYNCED],
-               },
                genius: {
                        on: spotifyVersion >= "1.2.31" ? false : 
getConfig("lyrics-plus:provider:genius:on"),
                        desc: "Provide unsynced lyrics with insights from 
artists themselves. Genius is disabled and cannot be used as a provider on 
<code>1.2.31</code> and higher.",
@@ -175,9 +175,10 @@
                this.styleVariables = {};
                this.fullscreenContainer = document.createElement("div");
                this.fullscreenContainer.id = "lyrics-fullscreen-container";
-               this.mousetrap = new Spicetify.Mousetrap();
+               this.mousetrap = null;
                this.containerRef = react.createRef(null);
                this.translator = null;
+               this.initMoustrap();
                // Cache last state
                this.languageOverride = 
CONFIG.visual["translate:detect-language-override"];
                this.translate = CONFIG.visual.translate;
@@ -647,6 +648,11 @@
                reader.readAsText(file[0]);
                event.target.value = "";
        }
+       initMoustrap() {
+               if (!this.mousetrap && Spicetify.Mousetrap) {
+                       this.mousetrap = new Spicetify.Mousetrap();
+               }
+       }
 
        componentDidMount() {
                this.onQueueChange = async ({ data: queue }) => {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cli-2.39.3/CustomApps/lyrics-plus/style.css 
new/cli-2.39.5/CustomApps/lyrics-plus/style.css
--- old/cli-2.39.3/CustomApps/lyrics-plus/style.css     2025-02-14 
18:20:05.000000000 +0100
+++ new/cli-2.39.5/CustomApps/lyrics-plus/style.css     2025-03-01 
00:22:37.000000000 +0100
@@ -704,6 +704,9 @@
 .split .lyrics-versionSelector select {
        width: 100%;
 }
+.main-content-view {
+       height: 100%;
+}
 
 @media (min-width: 1024px) {
        .split .lyrics-lyricsContainer-LyricsLine {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cli-2.39.3/Extensions/popupLyrics.js 
new/cli-2.39.5/Extensions/popupLyrics.js
--- old/cli-2.39.3/Extensions/popupLyrics.js    2025-02-14 18:20:05.000000000 
+0100
+++ new/cli-2.39.5/Extensions/popupLyrics.js    2025-03-01 00:22:37.000000000 
+0100
@@ -18,6 +18,7 @@
                        num = setInterval(() => 
postMessage("popup-lyric-update-ui"), 16.66);
                } else if (event.data === "popup-lyric-stop-update") {
                        clearInterval(num);
+                       postMessage("popup-lyric-update-ui");
                        num = null;
                }
        };
@@ -25,6 +26,8 @@
        PopupLyrics();
 }
 
+let CACHE = {};
+
 function PopupLyrics() {
        const { Player, CosmosAsync, LocalStorage, ContextMenu } = Spicetify;
 
@@ -40,6 +43,21 @@
                }
        };
 
+       let workerIsRunning = null;
+       document.addEventListener("visibilitychange", (e) => {
+               if (e.target.hidden) {
+                       if (!workerIsRunning) {
+                               
worker.postMessage("popup-lyric-request-update");
+                               workerIsRunning = true;
+                       }
+               } else {
+                       if (workerIsRunning) {
+                               worker.postMessage("popup-lyric-stop-update");
+                               workerIsRunning = false;
+                       }
+               }
+       });
+
        const LyricUtils = {
                normalize(s, emptySymbol = true) {
                        const result = s
@@ -324,7 +342,7 @@
                        musixmatch: {
                                on: 
boolLocalStorage("popup-lyrics:services:musixmatch:on"),
                                call: LyricProviders.fetchMusixmatch,
-                               desc: `Fully compatible with Spotify. Requires 
a token that can be retrieved from the official Musixmatch app. Follow 
instructions on <a 
href="https://spicetify.app/docs/faq#sometimes-popup-lyrics-andor-lyrics-plus-seem-to-not-work";>Spicetify
 Docs</a>.`,
+                               desc: "Fully compatible with Spotify. Requires 
a token that can be retrieved from the official Musixmatch app. If you have 
problems with retrieving lyrics, try refreshing the token by clicking 
<code>Refresh Token</code> button.",
                                token: 
LocalStorage.get("popup-lyrics:services:musixmatch:token") || 
"2005218b74f939209bda92cb633c7380612e14cb7fe92dcd6a780f",
                        },
                        spotify: {
@@ -421,9 +439,11 @@
 
        let sharedData = {};
 
-       Player.addEventListener("songchange", updateTrack);
+       Player.addEventListener("songchange", () => {
+               updateTrack();
+       });
 
-       async function updateTrack() {
+       async function updateTrack(refresh = false) {
                if (!lyricVideoIsOpen) {
                        return;
                }
@@ -443,20 +463,25 @@
                        uri: Player.data.item.uri,
                };
 
-               for (const name of userConfigs.servicesOrder) {
-                       const service = userConfigs.services[name];
-                       if (!service.on) continue;
-                       sharedData = { lyrics: [] };
+               if (CACHE?.[info.uri]?.lyrics?.length && !refresh) {
+                       sharedData = CACHE[info.uri];
+               } else {
+                       for (const name of userConfigs.servicesOrder) {
+                               const service = userConfigs.services[name];
+                               if (!service.on) continue;
+                               sharedData = { lyrics: [] };
+
+                               try {
+                                       const data = await service.call(info);
+                                       sharedData = data;
+                                       CACHE[info.uri] = sharedData;
 
-                       try {
-                               const data = await service.call(info);
-                               console.log(data);
-                               sharedData = data;
-                               if (!sharedData.error) {
-                                       return;
+                                       if (!sharedData.error) {
+                                               return;
+                                       }
+                               } catch (err) {
+                                       sharedData = { error: "No lyrics" };
                                }
-                       } catch (err) {
-                               sharedData = { error: "No lyrics" };
                        }
                }
        }
@@ -755,7 +780,6 @@
                ctx.restore();
        }
 
-       let workerIsRunning = null;
        let timeout = null;
 
        async function tick(options) {
@@ -791,17 +815,7 @@
                        return;
                }
 
-               if (document.hidden) {
-                       if (!workerIsRunning) {
-                               
worker.postMessage("popup-lyric-request-update");
-                               workerIsRunning = true;
-                       }
-               } else {
-                       if (workerIsRunning) {
-                               worker.postMessage("popup-lyric-stop-update");
-                               workerIsRunning = false;
-                       }
-
+               if (!document.hidden) {
                        requestAnimationFrame(() => tick(options));
                }
        }
@@ -815,11 +829,20 @@
 
        function openConfig(event) {
                event.preventDefault();
-               if (!configContainer) {
+
+               // Reset on reopen
+               if (configContainer) {
+                       resetTokenButton(configContainer);
+               } else {
                        configContainer = document.createElement("div");
                        configContainer.id = "popup-config-container";
                        const style = document.createElement("style");
                        style.innerHTML = `
+.setting-row {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+}
 .setting-row::after {
     content: "";
     display: table;
@@ -831,13 +854,16 @@
     align-items: center;
 }
 .setting-row .col.description {
-    float: left;
     padding-right: 15px;
     cursor: default;
+    width: 50%;
 }
 .setting-row .col.action {
-    float: right;
-    text-align: right;
+    justify-content: flex-end;
+    width: 50%;
+}
+.popup-config-col-margin {
+    margin-top: 10px;
 }
 button.switch {
     align-items: center;
@@ -859,6 +885,27 @@
     height: 22px;
     padding: 6px;
 }
+button.btn {
+    font-weight: 700;
+    display: block;
+    background-color: rgba(var(--spice-rgb-shadow), .7);
+    border-radius: 500px;
+    transition-duration: 33ms;
+    transition-property: background-color, border-color, color, box-shadow, 
filter, transform;
+    padding-inline: 15px;
+    border: 1px solid #727272;
+    color: var(--spice-text);
+    min-block-size: 32px;
+    cursor: pointer;
+}
+button.btn:hover {
+    transform: scale(1.04);
+    border-color: var(--spice-text);
+}
+button.btn:disabled {
+    opacity: 0.5;
+    cursor: not-allowed;
+}
 #popup-config-container select {
     color: var(--spice-text);
     background: rgba(var(--spice-rgb-shadow), .7);
@@ -867,7 +914,6 @@
 }
 #popup-config-container input {
     width: 100%;
-    margin-top: 10px;
     padding: 0 5px;
     height: 32px;
     border: 0;
@@ -945,6 +991,13 @@
                                userConfigs.delay = Number(state);
                                LocalStorage.set("popup-lyrics:delay", state);
                        });
+                       const clearCache = descriptiveElement(
+                               createButton("Clear Memory Cache", "Clear 
Memory Cache", () => {
+                                       CACHE = {};
+                                       updateTrack();
+                               }),
+                               "Loaded lyrics are cached in memory for faster 
reloading. Press this button to clear the cached lyrics from memory without 
restarting Spotify."
+                       );
 
                        const serviceHeader = document.createElement("h2");
                        serviceHeader.innerText = "Services";
@@ -975,7 +1028,7 @@
                                const id = el.dataset.id;
                                userConfigs.services[id].on = state;
                                
LocalStorage.set(`popup-lyrics:services:${id}:on`, state);
-                               updateTrack();
+                               updateTrack(true);
                        }
 
                        function posCallback(el, dir) {
@@ -990,23 +1043,28 @@
                                LocalStorage.set("popup-lyrics:services-order", 
JSON.stringify(userConfigs.servicesOrder));
 
                                stackServiceElements();
-                               updateTrack();
-                       }
-
-                       function tokenChangeCallback(el, inputEl) {
-                               const newVal = inputEl.value;
-                               const id = el.dataset.id;
-                               userConfigs.services[id].token = newVal;
-                               
LocalStorage.set(`popup-lyrics:services:${id}:token`, newVal);
-                               updateTrack();
+                               updateTrack(true);
                        }
 
                        for (const name of userConfigs.servicesOrder) {
-                               userConfigs.services[name].element = 
createServiceOption(name, userConfigs.services[name], switchCallback, 
posCallback, tokenChangeCallback);
+                               userConfigs.services[name].element = 
createServiceOption(name, userConfigs.services[name], switchCallback, 
posCallback);
                        }
                        stackServiceElements();
 
-                       configContainer.append(style, optionHeader, smooth, 
center, cover, blurSize, fontSize, ratio, delay, serviceHeader, 
serviceContainer);
+                       configContainer.append(
+                               style,
+                               optionHeader,
+                               smooth,
+                               center,
+                               cover,
+                               blurSize,
+                               fontSize,
+                               ratio,
+                               delay,
+                               clearCache,
+                               serviceHeader,
+                               serviceContainer
+                       );
                }
                Spicetify.PopupModal.display({
                        title: "Popup Lyrics",
@@ -1084,8 +1142,125 @@
 
                return container;
        }
+       // if name is null, the element can be used without a description.
+       function createButton(name, defaultValue, callback) {
+               let container;
+
+               if (name) {
+                       container = document.createElement("div");
+                       container.innerHTML = `
+               <div class="setting-row">
+               <label class="col description">${name}</label>
+               <div class="col action">
+                       <button id="popup-lyrics-clickbutton" 
class="btn">${defaultValue}</button>
+               </div>
+               </div>`;
+
+                       const button = 
container.querySelector("#popup-lyrics-clickbutton");
+                       button.onclick = () => {
+                               callback();
+                       };
+               } else {
+                       container = document.createElement("button");
+                       container.innerHTML = defaultValue;
+                       container.className = "btn ";
+
+                       container.onclick = () => {
+                               callback();
+                       };
+               }
+
+               return container;
+       }
+       // if name is null, the element can be used without a description.
+       function createTextfield(name, defaultValue, placeholder, callback) {
+               let container;
+
+               if (name) {
+                       container = document.createElement("div");
+                       container.className = "setting-column";
+                       container.innerHTML = `
+                       <label class="row-description">${name}</label>
+                       <div class="popup-row-option action">
+                               <input id="popup-lyrics-textfield" 
placeholder="${placeholder}" value="${defaultValue}" />
+                       </div>`;
+
+                       const textfield = 
container.querySelector("#popup-lyrics-textfield");
+                       textfield.onchange = () => {
+                               callback();
+                       };
+               } else {
+                       container = document.createElement("input");
+                       container.placeholder = placeholder;
+                       container.value = defaultValue;
+
+                       container.onchange = (e) => {
+                               callback(e.target.value);
+                       };
+               }
+
+               return container;
+       }
+       function descriptiveElement(element, description) {
+               const desc = document.createElement("span");
+               desc.innerHTML = description;
+               element.append(desc);
+               return element;
+       }
+
+       function resetTokenButton(container) {
+               const button = 
container.querySelector("#popup-lyrics-refresh-token");
+               if (button) {
+                       button.innerHTML = "Refresh token";
+                       button.disabled = false;
+               }
+       }
+
+       function musixmatchTokenElements(defaultVal, id) {
+               const button = createButton(null, "Refresh token", 
clickRefresh);
+               button.className += "popup-config-col-margin";
+               button.id = "popup-lyrics-refresh-token";
+               const textfield = createTextfield(null, defaultVal.token, 
`Place your ${id} token here`, changeTokenfield);
+               textfield.className += "popup-config-col-margin";
+
+               function clickRefresh() {
+                       button.innerHTML = "Refreshing token...";
+                       button.disabled = true;
+
+                       
Spicetify.CosmosAsync.get("https://apic-desktop.musixmatch.com/ws/1.1/token.get?app_id=web-desktop-app-v1.0";,
 null, {
+                               authority: "apic-desktop.musixmatch.com",
+                       })
+                               .then(({ message: response }) => {
+                                       if (response.header.status_code === 200 
&& response.body.user_token) {
+                                               button.innerHTML = "Token 
refreshed";
+                                               textfield.value = 
response.body.user_token;
+                                               textfield.dispatchEvent(new 
Event("change"));
+                                       } else if (response.header.status_code 
=== 401) {
+                                               button.innerHTML = "Too many 
attempts";
+                                       } else {
+                                               button.innerHTML = "Failed to 
refresh token";
+                                               console.error("Failed to 
refresh token", response);
+                                       }
+                               })
+                               .catch((error) => {
+                                       button.innerHTML = "Failed to refresh 
token";
+                                       console.error("Failed to refresh 
token", error);
+                               });
+               }
+
+               function changeTokenfield(value) {
+                       userConfigs.services.musixmatch.token = value;
+                       
LocalStorage.set("popup-lyrics:services:musixmatch:token", value);
+                       updateTrack(true);
+               }
+
+               const container = document.createElement("div");
+               container.append(button);
+               container.append(textfield);
+               return container;
+       }
 
-       function createServiceOption(id, defaultVal, switchCallback, 
posCallback, tokenCallback) {
+       function createServiceOption(id, defaultVal, switchCallback, 
posCallback) {
                const name = id.replace(/^./, (c) => c.toUpperCase());
 
                const container = document.createElement("div");
@@ -1113,12 +1288,8 @@
 </div>
 <span>${defaultVal.desc}</span>`;
 
-               if (defaultVal.token !== undefined) {
-                       const input = document.createElement("input");
-                       input.placeholder = `Place your ${id} token here`;
-                       input.value = defaultVal.token;
-                       input.onchange = () => tokenCallback(container, input);
-                       container.append(input);
+               if (id === "musixmatch") {
+                       container.append(musixmatchTokenElements(defaultVal));
                }
 
                const [up, down, slider] = container.querySelectorAll("button");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cli-2.39.3/css-map.json new/cli-2.39.5/css-map.json
--- old/cli-2.39.3/css-map.json 2025-02-14 18:20:05.000000000 +0100
+++ new/cli-2.39.5/css-map.json 2025-03-01 00:22:37.000000000 +0100
@@ -271,6 +271,7 @@
        "X05XDhpQJ7THPHfgbUk1": "main-confirmDialog-buttonContainer",
        "RVgHI2ejYct8LjT1AO7m": "main-confirmDialog-container",
        "m0yIuS1Q6XRA5R4PNEhl": "main-confirmDialog-overlay",
+       "KL8t9WB65UfUEPuTFAhO": "main-content-view",
        "gQoa8JTSpjSmYyABcag2": "main-connectBar-connectBar",
        "T3hkVxXuSbCYOD2GIeQd": "main-connectBar-connected",
        "GcHojieewpdN1c8vbtwk": "main-connectBar-connecting",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cli-2.39.3/globals.d.ts new/cli-2.39.5/globals.d.ts
--- old/cli-2.39.3/globals.d.ts 2025-02-14 18:20:05.000000000 +0100
+++ new/cli-2.39.5/globals.d.ts 2025-03-01 00:22:37.000000000 +0100
@@ -540,6 +540,7 @@
         * @param uri Any type of URI that has artwork (playlist, track, album, 
artist, show, ...)
         */
        function colorExtractor(uri: string): Promise<{
+               DARK_VIBRANT: string;
                DESATURATED: string;
                LIGHT_VIBRANT: string;
                PROMINENT: string;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cli-2.39.3/spicetify.go new/cli-2.39.5/spicetify.go
--- old/cli-2.39.3/spicetify.go 2025-02-14 18:20:05.000000000 +0100
+++ new/cli-2.39.5/spicetify.go 2025-03-01 00:22:37.000000000 +0100
@@ -17,6 +17,7 @@
        "github.com/spicetify/cli/src/cmd"
        spotifystatus "github.com/spicetify/cli/src/status/spotify"
        "github.com/spicetify/cli/src/utils"
+       "github.com/spicetify/cli/src/utils/isAdmin"
 )
 
 var (
@@ -24,14 +25,15 @@
 )
 
 var (
-       flags          = []string{}
-       commands       = []string{}
-       quiet          = false
-       extensionFocus = false
-       appFocus       = false
-       styleFocus     = false
-       noRestart      = false
-       liveRefresh    = false
+       flags            = []string{}
+       commands         = []string{}
+       quiet            = false
+       extensionFocus   = false
+       appFocus         = false
+       styleFocus       = false
+       noRestart        = false
+       liveRefresh      = false
+       bypassAdminCheck = false
 )
 
 func init() {
@@ -66,6 +68,8 @@
 
        for _, v := range flags {
                switch v {
+               case "--bypass-admin":
+                       bypassAdminCheck = true
                case "-c", "--config":
                        fmt.Println(cmd.GetConfigPath())
                        os.Exit(0)
@@ -110,6 +114,22 @@
                os.Stdout = nil
        }
 
+       if isAdmin.Check(bypassAdminCheck) {
+               utils.PrintError("Spicetify should not be run with 
administrator/root privileges")
+               utils.PrintError("Running as admin can cause Spotify to show a 
black/blank window after applying spicetify")
+               utils.PrintError("This happens because Spotify (running as a 
normal user) can't access files modified with admin privileges")
+               utils.PrintInfo("If you understand the risks and need to 
continue anyway, you can use the '--bypass-admin' flag.")
+               utils.PrintInfo("Spicetify is now exiting...")
+               os.Exit(1)
+       }
+
+       for i, flag := range flags {
+               if flag == "--bypass-admin" {
+                       flags = append(flags[:i], flags[i+1:]...)
+                       break
+               }
+       }
+
        utils.MigrateConfigFolder()
        utils.MigrateFolders()
        cmd.InitConfig(quiet)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cli-2.39.3/src/preprocess/preprocess.go 
new/cli-2.39.5/src/preprocess/preprocess.go
--- old/cli-2.39.3/src/preprocess/preprocess.go 2025-02-14 18:20:05.000000000 
+0100
+++ new/cli-2.39.5/src/preprocess/preprocess.go 2025-03-01 00:22:37.000000000 
+0100
@@ -142,7 +142,7 @@
                                }
                                if fileName == "xpui.css" {
                                        content = content + `
-                                       
.main-gridContainer-fixedWidth{grid-template-columns: repeat(auto-fill, 
var(--column-width));width: calc((var(--column-count) - 1) * var(--grid-gap)) + 
var(--column-count) * 
var(--column-width));}.main-cardImage-imageWrapper{background-color: 
var(--card-color, #333);border-radius: 6px;-webkit-box-shadow: 0 8px 24px 
rgba(0, 0, 0, .5);box-shadow: 0 8px 24px rgba(0, 0, 0, .5);padding-bottom: 
100%;position: 
relative;width:100%;}.main-cardImage-image,.main-card-imagePlaceholder{height: 
100%;left: 0;position: absolute;top: 0;width: 100%}
+                                       
.main-gridContainer-fixedWidth{grid-template-columns: repeat(auto-fill, 
var(--column-width));width: calc((var(--column-count) - 1) * var(--grid-gap)) + 
var(--column-count) * 
var(--column-width));}.main-cardImage-imageWrapper{background-color: 
var(--card-color, #333);border-radius: 6px;-webkit-box-shadow: 0 8px 24px 
rgba(0, 0, 0, .5);box-shadow: 0 8px 24px rgba(0, 0, 0, .5);padding-bottom: 
100%;position: 
relative;width:100%;}.main-cardImage-image,.main-card-imagePlaceholder{height: 
100%;left: 0;position: absolute;top: 0;width: 
100%};.main-content-view{height:100%;}
                                        `
                                }
                                return content
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cli-2.39.3/src/utils/isAdmin/unix.go 
new/cli-2.39.5/src/utils/isAdmin/unix.go
--- old/cli-2.39.3/src/utils/isAdmin/unix.go    1970-01-01 01:00:00.000000000 
+0100
+++ new/cli-2.39.5/src/utils/isAdmin/unix.go    2025-03-01 00:22:37.000000000 
+0100
@@ -0,0 +1,13 @@
+//go:build !windows
+// +build !windows
+
+package isAdmin
+
+import "os"
+
+func Check(bypassAdminCheck bool) bool {
+       if bypassAdminCheck {
+               return false
+       }
+       return os.Geteuid() == 0
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cli-2.39.3/src/utils/isAdmin/windows.go 
new/cli-2.39.5/src/utils/isAdmin/windows.go
--- old/cli-2.39.3/src/utils/isAdmin/windows.go 1970-01-01 01:00:00.000000000 
+0100
+++ new/cli-2.39.5/src/utils/isAdmin/windows.go 2025-03-01 00:22:37.000000000 
+0100
@@ -0,0 +1,31 @@
+//go:build windows
+// +build windows
+
+package isAdmin
+
+import (
+       "golang.org/x/sys/windows"
+)
+
+func Check(bypassAdminCheck bool) bool {
+       if bypassAdminCheck {
+               return false
+       }
+
+       var sid *windows.SID
+       err := windows.AllocateAndInitializeSid(
+               &windows.SECURITY_NT_AUTHORITY,
+               2,
+               windows.SECURITY_BUILTIN_DOMAIN_RID,
+               windows.DOMAIN_ALIAS_RID_ADMINS,
+               0, 0, 0, 0, 0, 0,
+               &sid)
+       if err != nil {
+               return false
+       }
+       defer windows.FreeSid(sid)
+
+       token := windows.Token(0)
+       member, err := token.IsMember(sid)
+       return err == nil && member
+}

++++++ cli.obsinfo ++++++
--- /var/tmp/diff_new_pack.uK3rm8/_old  2025-03-13 15:08:43.340554371 +0100
+++ /var/tmp/diff_new_pack.uK3rm8/_new  2025-03-13 15:08:43.372555713 +0100
@@ -1,5 +1,5 @@
 name: cli
-version: 2.39.3
-mtime: 1739553605
-commit: 0414d766239b51f1d6cff6802c9fb361e4a64fe4
+version: 2.39.5
+mtime: 1740784957
+commit: c99cdf6673e1a81a64a426117538b19c042e4f3e
 

++++++ vendor.tar.gz ++++++

Reply via email to