chore: theme script migration (#912)

This commit is contained in:
Thomas Fitzpatrick 2023-04-16 01:43:55 +01:00 committed by GitHub
parent 58a709916a
commit 0213a8e482
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 278 additions and 293 deletions

View File

@ -57,11 +57,8 @@ Run these commands:
In **Bash**: In **Bash**:
```bash ```bash
cd "$(dirname "$(spicetify -c)")/Themes/Dribbblish" cd "$(dirname "$(spicetify -c)")/Themes/Dribbblish"
mkdir -p ../../Extensions
cp dribbblish.js ../../Extensions/.
spicetify config extensions dribbblish.js
spicetify config current_theme Dribbblish color_scheme base spicetify config current_theme Dribbblish color_scheme base
spicetify config inject_css 1 replace_colors 1 overwrite_assets 1 spicetify config inject_css 1 replace_colors 1 overwrite_assets 1 inject_theme_js 1
spicetify apply spicetify apply
``` ```
@ -69,10 +66,8 @@ spicetify apply
In **Powershell**: In **Powershell**:
```powershell ```powershell
cd "$(spicetify -c | Split-Path)\Themes\Dribbblish" cd "$(spicetify -c | Split-Path)\Themes\Dribbblish"
Copy-Item dribbblish.js ..\..\Extensions
spicetify config extensions dribbblish.js
spicetify config current_theme Dribbblish color_scheme base spicetify config current_theme Dribbblish color_scheme base
spicetify config inject_css 1 replace_colors 1 overwrite_assets 1 spicetify config inject_css 1 replace_colors 1 overwrite_assets 1 inject_theme_js 1
spicetify apply spicetify apply
``` ```
@ -97,12 +92,9 @@ Invoke-WebRequest -UseBasicParsing "https://raw.githubusercontent.com/spicetify/
``` ```
## Manual uninstall ## Manual uninstall
Remove the dribbblish script with the following commands Remove the dribbblish theme with the following commands
``` ```
spicetify config extensions dribbblish.js- spicetify config current_theme " " color_scheme " "
```
And remove Patch lines you added in config file earlier. Finally, run:
```
spicetify apply spicetify apply
``` ```

View File

@ -26,13 +26,9 @@ if (Test-Path $destPath) {
} }
Copy-Item $dribPath $destPath -Recurse Copy-Item $dribPath $destPath -Recurse
# Copy extension file
New-Item -ItemType Directory -Force "$spicePath\Extensions"
Copy-Item "$destPath\dribbblish.js" "$spicePath\Extensions"
Write-Host "Configuring:" -ForegroundColor Green Write-Host "Configuring:" -ForegroundColor Green
spicetify spicetify
spicetify config inject_css 1 replace_colors 1 overwrite_assets 1 current_theme Dribbblish extensions dribbblish.js spicetify config inject_css 1 replace_colors 1 overwrite_assets 1 inject_theme_js 1 current_theme Dribbblish
# Add patch # Add patch
$configFile = Get-Content "$spicePath\config-xpui.ini" $configFile = Get-Content "$spicePath\config-xpui.ini"

View File

@ -1,266 +1,266 @@
// Hide popover message // Hide popover message
// document.getElementById("popover-container").style.height = 0; // document.getElementById("popover-container").style.height = 0;
const DribbblishShared = { const DribbblishShared = {
configMenu: new Spicetify.Menu.SubMenu("Dribbblish", []), configMenu: new Spicetify.Menu.SubMenu("Dribbblish", []),
rightBigCover: localStorage.getItem("dribs-right-big-cover") === "true", rightBigCover: localStorage.getItem("dribs-right-big-cover") === "true",
setRightBigCover: () => { setRightBigCover: () => {
if (DribbblishShared.rightBigCover) { if (DribbblishShared.rightBigCover) {
document.documentElement.classList.add("right-expanded-cover"); document.documentElement.classList.add("right-expanded-cover");
} else { } else {
document.documentElement.classList.remove("right-expanded-cover"); document.documentElement.classList.remove("right-expanded-cover");
} }
} }
}; };
// register drib menu item // register drib menu item
DribbblishShared.configMenu.register(); DribbblishShared.configMenu.register();
DribbblishShared.configMenu.addItem(new Spicetify.Menu.Item( DribbblishShared.configMenu.addItem(new Spicetify.Menu.Item(
"Right expanded cover", "Right expanded cover",
DribbblishShared.rightBigCover, DribbblishShared.rightBigCover,
(self) => { (self) => {
self.isEnabled = !self.isEnabled; self.isEnabled = !self.isEnabled;
DribbblishShared.rightBigCover = self.isEnabled; DribbblishShared.rightBigCover = self.isEnabled;
localStorage.setItem("dribs-right-big-cover", self.isEnabled); localStorage.setItem("dribs-right-big-cover", self.isEnabled);
DribbblishShared.setRightBigCover(); DribbblishShared.setRightBigCover();
} }
)); ));
DribbblishShared.setRightBigCover(); DribbblishShared.setRightBigCover();
function waitForElement(els, func, timeout = 100) { function waitForElement(els, func, timeout = 100) {
const queries = els.map(el => document.querySelector(el)); const queries = els.map(el => document.querySelector(el));
if (queries.every(a => a)) { if (queries.every(a => a)) {
func(queries); func(queries);
} else if (timeout > 0) { } else if (timeout > 0) {
setTimeout(waitForElement, 300, els, func, --timeout); setTimeout(waitForElement, 300, els, func, --timeout);
} }
} }
waitForElement([ waitForElement([
`ul[tabindex="0"]`, `ul[tabindex="0"]`,
`ul[tabindex="0"] .GlueDropTarget--playlists.GlueDropTarget--folders` `ul[tabindex="0"] .GlueDropTarget--playlists.GlueDropTarget--folders`
], ([root, firstItem]) => { ], ([root, firstItem]) => {
const listElem = firstItem.parentElement; const listElem = firstItem.parentElement;
root.classList.add("dribs-playlist-list"); root.classList.add("dribs-playlist-list");
/** Replace Playlist name with their pictures */ /** Replace Playlist name with their pictures */
function loadPlaylistImage() { function loadPlaylistImage() {
for (const item of listElem.children) { for (const item of listElem.children) {
let link = item.querySelector("a"); let link = item.querySelector("a");
if (!link) continue; if (!link) continue;
let [_, app, uid ] = link.pathname.split("/"); let [_, app, uid ] = link.pathname.split("/");
let uri; let uri;
if (app === "playlist") { if (app === "playlist") {
uri = `spotify:playlist:${uid}`; uri = `spotify:playlist:${uid}`;
} else if (app === "folder") { } else if (app === "folder") {
const base64 = localStorage.getItem("dribbblish:folder-image:" + uid); const base64 = localStorage.getItem("dribbblish:folder-image:" + uid);
let img = link.querySelector("img"); let img = link.querySelector("img");
if (!img) { if (!img) {
img = document.createElement("img"); img = document.createElement("img");
img.classList.add("playlist-picture"); img.classList.add("playlist-picture");
link.prepend(img); link.prepend(img);
} }
img.src = base64 || "https://cdn.jsdelivr.net/gh/spicetify/spicetify-themes@master/Dribbblish/images/tracklist-row-song-fallback.svg"; img.src = base64 || "https://cdn.jsdelivr.net/gh/spicetify/spicetify-themes@master/Dribbblish/images/tracklist-row-song-fallback.svg";
continue; continue;
} }
Spicetify.CosmosAsync.get( Spicetify.CosmosAsync.get(
`sp://core-playlist/v1/playlist/${uri}/metadata`, `sp://core-playlist/v1/playlist/${uri}/metadata`,
{ policy: { picture: true } } { policy: { picture: true } }
).then(res => { ).then(res => {
const meta = res.metadata; const meta = res.metadata;
let img = link.querySelector("img"); let img = link.querySelector("img");
if (!img) { if (!img) {
img = document.createElement("img"); img = document.createElement("img");
img.classList.add("playlist-picture"); img.classList.add("playlist-picture");
link.prepend(img); link.prepend(img);
} }
img.src = meta.picture || "https://cdn.jsdelivr.net/gh/spicetify/spicetify-themes@master/Dribbblish/images/tracklist-row-song-fallback.svg"; img.src = meta.picture || "https://cdn.jsdelivr.net/gh/spicetify/spicetify-themes@master/Dribbblish/images/tracklist-row-song-fallback.svg";
}); });
} }
} }
DribbblishShared.loadPlaylistImage = loadPlaylistImage; DribbblishShared.loadPlaylistImage = loadPlaylistImage;
loadPlaylistImage(); loadPlaylistImage();
new MutationObserver(loadPlaylistImage) new MutationObserver(loadPlaylistImage)
.observe(listElem, {childList: true}); .observe(listElem, {childList: true});
}); });
waitForElement([".Root__top-container"], ([topContainer]) => { waitForElement([".Root__top-container"], ([topContainer]) => {
const shadow = document.createElement("div"); const shadow = document.createElement("div");
shadow.id = "dribbblish-back-shadow"; shadow.id = "dribbblish-back-shadow";
topContainer.prepend(shadow); topContainer.prepend(shadow);
}); });
// allow resizing of the navbar // allow resizing of the navbar
waitForElement([ waitForElement([
".Root__nav-bar .LayoutResizer__input, .Root__nav-bar .LayoutResizer__resize-bar input" ".Root__nav-bar .LayoutResizer__input, .Root__nav-bar .LayoutResizer__resize-bar input"
], ([resizer]) => { ], ([resizer]) => {
const observer = new MutationObserver(updateVariable); const observer = new MutationObserver(updateVariable);
observer.observe(resizer, { attributes: true, attributeFilter: ["value"]}); observer.observe(resizer, { attributes: true, attributeFilter: ["value"]});
function updateVariable() { function updateVariable() {
let value = resizer.value; let value = resizer.value;
if (value < 121) { if (value < 121) {
value = 72; value = 72;
document.documentElement.classList.add("sidebar-hide-text"); document.documentElement.classList.add("sidebar-hide-text");
} else { } else {
document.documentElement.classList.remove("sidebar-hide-text"); document.documentElement.classList.remove("sidebar-hide-text");
} }
document.documentElement.style.setProperty( document.documentElement.style.setProperty(
"--sidebar-width", value + "px"); "--sidebar-width", value + "px");
} }
updateVariable(); updateVariable();
}); });
// allow resizing of the buddy feed // allow resizing of the buddy feed
waitForElement([".Root__right-sidebar .LayoutResizer__input, .Root__right-sidebar .LayoutResizer__resize-bar input"], ([resizer]) => { waitForElement([".Root__right-sidebar .LayoutResizer__input, .Root__right-sidebar .LayoutResizer__resize-bar input"], ([resizer]) => {
const observer = new MutationObserver(updateVariable); const observer = new MutationObserver(updateVariable);
observer.observe(resizer, { attributes: true, attributeFilter: ["value"] }); observer.observe(resizer, { attributes: true, attributeFilter: ["value"] });
function updateVariable() { function updateVariable() {
let value = resizer.value; let value = resizer.value;
if (value == 320) { if (value == 320) {
value = 72; value = 72;
document.documentElement.classList.add("buddyFeed-hide-text"); document.documentElement.classList.add("buddyFeed-hide-text");
} else { } else {
document.documentElement.classList.remove("buddyFeed-hide-text"); document.documentElement.classList.remove("buddyFeed-hide-text");
} }
} }
updateVariable(); updateVariable();
}); });
// add fade effect on playlist/folder list // add fade effect on playlist/folder list
waitForElement([".main-navBar-navBar .os-viewport.os-viewport-native-scrollbars-invisible"], ([scrollNode]) => { waitForElement([".main-navBar-navBar .os-viewport.os-viewport-native-scrollbars-invisible"], ([scrollNode]) => {
scrollNode.setAttribute("fade", "bottom"); scrollNode.setAttribute("fade", "bottom");
scrollNode.addEventListener("scroll", () => { scrollNode.addEventListener("scroll", () => {
if (scrollNode.scrollTop == 0) { if (scrollNode.scrollTop == 0) {
scrollNode.setAttribute("fade", "bottom"); scrollNode.setAttribute("fade", "bottom");
} else if (scrollNode.scrollHeight - scrollNode.clientHeight - scrollNode.scrollTop == 0) { } else if (scrollNode.scrollHeight - scrollNode.clientHeight - scrollNode.scrollTop == 0) {
scrollNode.setAttribute("fade", "top"); scrollNode.setAttribute("fade", "top");
} else { } else {
scrollNode.setAttribute("fade", "full"); scrollNode.setAttribute("fade", "full");
} }
}); });
}); });
// improve styles at smaller sizes // improve styles at smaller sizes
waitForElement([".Root__main-view .os-resize-observer-host"], ([resizeHost]) => { waitForElement([".Root__main-view .os-resize-observer-host"], ([resizeHost]) => {
const observer = new ResizeObserver(updateVariable); const observer = new ResizeObserver(updateVariable);
observer.observe(resizeHost); observer.observe(resizeHost);
function updateVariable([ event ]) { function updateVariable([ event ]) {
document.documentElement.style.setProperty( document.documentElement.style.setProperty(
"--main-view-width", event.contentRect.width + "px"); "--main-view-width", event.contentRect.width + "px");
if (event.contentRect.width < 700) { if (event.contentRect.width < 700) {
document.documentElement.classList.add("minimal-player"); document.documentElement.classList.add("minimal-player");
} else { } else {
document.documentElement.classList.remove("minimal-player"); document.documentElement.classList.remove("minimal-player");
} }
if (event.contentRect.width < 550) { if (event.contentRect.width < 550) {
document.documentElement.classList.add("extra-minimal-player"); document.documentElement.classList.add("extra-minimal-player");
} else { } else {
document.documentElement.classList.remove("extra-minimal-player"); document.documentElement.classList.remove("extra-minimal-player");
} }
} }
}); });
(function Dribbblish() { (function Dribbblish() {
// dynamic playback time tooltip // dynamic playback time tooltip
const progBar = document.querySelector(".playback-bar"); const progBar = document.querySelector(".playback-bar");
const root = document.querySelector(".Root"); const root = document.querySelector(".Root");
if (!Spicetify.Player.origin || !progBar || !root) { if (!Spicetify.Player.origin || !progBar || !root) {
setTimeout(Dribbblish, 300); setTimeout(Dribbblish, 300);
return; return;
} }
const tooltip = document.createElement("div"); const tooltip = document.createElement("div");
tooltip.className = "prog-tooltip"; tooltip.className = "prog-tooltip";
progBar.append(tooltip); progBar.append(tooltip);
const progKnob = progBar.querySelector(".progress-bar__slider"); const progKnob = progBar.querySelector(".progress-bar__slider");
function updateProgTime({ data: e }) { function updateProgTime({ data: e }) {
const offsetX = progKnob.offsetLeft + progKnob.offsetWidth / 2; const offsetX = progKnob.offsetLeft + progKnob.offsetWidth / 2;
const maxWidth = progBar.offsetWidth; const maxWidth = progBar.offsetWidth;
const curWidth = Spicetify.Player.getProgressPercent() * maxWidth; const curWidth = Spicetify.Player.getProgressPercent() * maxWidth;
const ttWidth = tooltip.offsetWidth / 2; const ttWidth = tooltip.offsetWidth / 2;
if (curWidth < ttWidth) { if (curWidth < ttWidth) {
tooltip.style.left = String(offsetX) + "px"; tooltip.style.left = String(offsetX) + "px";
} else if (curWidth > maxWidth - ttWidth) { } else if (curWidth > maxWidth - ttWidth) {
tooltip.style.left = String(offsetX - ttWidth * 2) + "px"; tooltip.style.left = String(offsetX - ttWidth * 2) + "px";
} else { } else {
tooltip.style.left = String(offsetX - ttWidth) + "px"; tooltip.style.left = String(offsetX - ttWidth) + "px";
} }
tooltip.innerText = Spicetify.Player.formatTime(e) + " / " + tooltip.innerText = Spicetify.Player.formatTime(e) + " / " +
Spicetify.Player.formatTime(Spicetify.Player.getDuration()); Spicetify.Player.formatTime(Spicetify.Player.getDuration());
} }
Spicetify.Player.addEventListener("onprogress", updateProgTime); Spicetify.Player.addEventListener("onprogress", updateProgTime);
updateProgTime({ data: Spicetify.Player.getProgress() }); updateProgTime({ data: Spicetify.Player.getProgress() });
Spicetify.CosmosAsync.sub("sp://connect/v1", (state) => { Spicetify.CosmosAsync.sub("sp://connect/v1", (state) => {
const isExternal = state.devices.some(a => a.is_active); const isExternal = state.devices.some(a => a.is_active);
if (isExternal) { if (isExternal) {
root.classList.add("is-connectBarVisible"); root.classList.add("is-connectBarVisible");
} else { } else {
root.classList.remove("is-connectBarVisible"); root.classList.remove("is-connectBarVisible");
} }
}); });
// filepicker for custom folder images // filepicker for custom folder images
const filePickerForm = document.createElement("form"); const filePickerForm = document.createElement("form");
filePickerForm.setAttribute("aria-hidden", true); filePickerForm.setAttribute("aria-hidden", true);
filePickerForm.innerHTML = '<input type="file" class="hidden-visually" />'; filePickerForm.innerHTML = '<input type="file" class="hidden-visually" />';
document.body.appendChild(filePickerForm); document.body.appendChild(filePickerForm);
/** @type {HTMLInputElement} */ /** @type {HTMLInputElement} */
const filePickerInput = filePickerForm.childNodes[0]; const filePickerInput = filePickerForm.childNodes[0];
filePickerInput.accept = [ filePickerInput.accept = [
"image/jpeg", "image/jpeg",
"image/apng", "image/apng",
"image/avif", "image/avif",
"image/gif", "image/gif",
"image/png", "image/png",
"image/svg+xml", "image/svg+xml",
"image/webp" "image/webp"
].join(","); ].join(",");
filePickerInput.onchange = () => { filePickerInput.onchange = () => {
if (!filePickerInput.files.length) return; if (!filePickerInput.files.length) return;
const file = filePickerInput.files[0]; const file = filePickerInput.files[0];
const reader = new FileReader; const reader = new FileReader;
reader.onload = (event) => { reader.onload = (event) => {
const result = event.target.result; const result = event.target.result;
const id = Spicetify.URI.from(filePickerInput.uri).id; const id = Spicetify.URI.from(filePickerInput.uri).id;
try { try {
localStorage.setItem( localStorage.setItem(
"dribbblish:folder-image:" + id, "dribbblish:folder-image:" + id,
result result
); );
} catch { } catch {
Spicetify.showNotification("File too large"); Spicetify.showNotification("File too large");
} }
DribbblishShared.loadPlaylistImage?.call(); DribbblishShared.loadPlaylistImage?.call();
} }
reader.readAsDataURL(file); reader.readAsDataURL(file);
} }
// context menu items for custom folder images // context menu items for custom folder images
new Spicetify.ContextMenu.Item("Remove folder image", new Spicetify.ContextMenu.Item("Remove folder image",
([uri]) => { ([uri]) => {
const id = Spicetify.URI.from(uri).id; const id = Spicetify.URI.from(uri).id;
localStorage.removeItem("dribbblish:folder-image:" + id); localStorage.removeItem("dribbblish:folder-image:" + id);
DribbblishShared.loadPlaylistImage?.call(); DribbblishShared.loadPlaylistImage?.call();
}, },
([uri]) => Spicetify.URI.isFolder(uri), ([uri]) => Spicetify.URI.isFolder(uri),
"x", "x",
).register(); ).register();
new Spicetify.ContextMenu.Item("Choose folder image", new Spicetify.ContextMenu.Item("Choose folder image",
([uri]) => { ([uri]) => {
filePickerInput.uri = uri; filePickerInput.uri = uri;
filePickerForm.reset(); filePickerForm.reset();
filePickerInput.click(); filePickerInput.click();
}, },
([uri]) => Spicetify.URI.isFolder(uri), ([uri]) => Spicetify.URI.isFolder(uri),
"edit", "edit",
).register(); ).register();
})(); })();

View File

@ -1,4 +1,4 @@
spicetify config current_theme " " extensions dribbblish.js- spicetify config current_theme " "
$configPath = spicetify -c $configPath = spicetify -c
$configFile = Get-Content $configPath $configFile = Get-Content $configPath

View File

@ -43,19 +43,18 @@ spicetify config extensions fullAppDisplay.js
spicetify apply spicetify apply
``` ```
2. put **Turntable** and **turntable.js** into the **.config/spicetify** 2. put **Turntable** into the **.config/spicetify**
```shell ```shell
cd spicetify-themes cd spicetify-themes
cp -r Turntable ~/.config/spicetify/Themes cp -r Turntable ~/.config/spicetify/Themes
cp Turntable/turntable.js ~/.config/spicetify/Extensions
``` ```
3. select the theme and extension, then apply 3. select the theme, then apply
```shell ```shell
spicetify config current_theme Turntable spicetify config current_theme Turntable
spicetify config extensions turntable.js spicetify config inject_theme_js 1
spicetify apply spicetify apply
``` ```
@ -65,7 +64,6 @@ spicetify apply
```shell ```shell
rm -r ~/.config/spicetify/Themes/Turntable rm -r ~/.config/spicetify/Themes/Turntable
rm ~/.config/spicetify/Extensions/turntable.js
``` ```
2. config to spicetify default theme 2. config to spicetify default theme
@ -74,11 +72,10 @@ rm ~/.config/spicetify/Extensions/turntable.js
spicetify config current_theme SpicetifyDefault spicetify config current_theme SpicetifyDefault
``` ```
3. remove extension - Full App Display and Turntable(optional) 3. remove extension - Full App Display
```shell ```shell
spicetify config extensions fullAppDisplay.js- spicetify config extensions fullAppDisplay.js-
spicetify config extensions turntable.js-
``` ```
4. apply 4. apply

View File

@ -49,7 +49,7 @@
"usercss": "Dribbblish/user.css", "usercss": "Dribbblish/user.css",
"schemes": "Dribbblish/color.ini", "schemes": "Dribbblish/color.ini",
"include": [ "include": [
"https://raw.githubusercontent.com/spicetify/spicetify-themes/master/Dribbblish/dribbblish.js" "https://raw.githubusercontent.com/spicetify/spicetify-themes/master/Dribbblish/theme.js"
], ],
"authors": [ "authors": [
{ {
@ -94,7 +94,7 @@
"usercss": "Turntable/user.css", "usercss": "Turntable/user.css",
"schemes": "Turntable/color.ini", "schemes": "Turntable/color.ini",
"include": [ "include": [
"https://raw.githubusercontent.com/spicetify/spicetify-themes/master/Turntable/turntable.js" "https://raw.githubusercontent.com/spicetify/spicetify-themes/master/Turntable/theme.js"
], ],
"authors": [ "authors": [
{ {