This repository was archived by the owner on Mar 9, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathqueueAll.js
More file actions
125 lines (112 loc) · 3.64 KB
/
queueAll.js
File metadata and controls
125 lines (112 loc) · 3.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
// @ts-check
// NAME: Queue All
// AUTHOR: khanhas
// DESCRIPTION: Add Queue All button in every album carousel.
/// <reference path="../globals.d.ts" />
(function QueueAll() {
if (!Spicetify.addToQueue) {
setTimeout(QueueAll, 1000);
return;
}
const BUTTON_TEXT = "Queue all";
const ADDING_TEXT = "Adding";
const ADDED_TEXT = "Added";
const COLLECTION_CLASSES =
"div.crsl-item.col-xs-12.col-sm-12.col-md-12.col-lg-12";
const ARTIST_CLASSES = ".albums, .singles, .appears_on";
const MOUNT_CLASSES = ".GlueCarousel, .Carousel";
const CARD_CLASSES =
".card, header.header.header-inline.header-album, .GlueCard, .Card";
const BROWSE_REGEXP = new RegExp(
/spotify:app:browse:(discover|releases|podcasts)/
);
function createQueueAllButton() {
const button = document.createElement("button");
button.classList.add(
"custom-queue-all",
"button",
"button-green",
"button-play"
);
button.innerText = BUTTON_TEXT;
button.style.marginLeft = "24px";
return button;
}
Spicetify.Player.addEventListener("appchange", ({ data: data }) => {
if (data.isEmbeddedApp === true) {
if (data.id === "album") {
findCarousel(data.container, MOUNT_CLASSES);
}
} else {
const doc = data.container.contentDocument;
if (BROWSE_REGEXP.test(data.uri)) {
findCarousel(doc, COLLECTION_CLASSES);
} else if (data.id === "artist") {
findCarousel(doc, ARTIST_CLASSES);
} else if (data.id === "genre") {
findCarousel(doc, COLLECTION_CLASSES);
}
}
});
/**
*
* @param {HTMLElement | Document} activeDoc
* @param {string} classes
* @param {number} retry
*/
function findCarousel(activeDoc, classes, retry = 0) {
if (retry > 10) return;
const crslItems = activeDoc.querySelectorAll(classes);
if (crslItems.length > 0) {
crslItems.forEach(appendQueueAll);
} else {
setTimeout(() => findCarousel(activeDoc, classes, ++retry), 1000);
}
}
/**
*
* @param {HTMLElement} item
*/
function appendQueueAll(item) {
const uris = [];
item.querySelectorAll(CARD_CLASSES).forEach((element) => {
const uri = element.getAttribute("data-uri");
uri && filterURI(uri) && uris.push(uri);
});
if (
item.querySelectorAll("button.custom-queue-all").length === 0 &&
uris.length > 0
) {
const h2 = item.querySelector("h2");
const button = createQueueAllButton();
button.onclick = () => {
button.innerText = ADDING_TEXT;
Spicetify.addToQueue(uris)
.then(() => {
button.innerText = ADDED_TEXT;
setTimeout(
() => (button.innerText = BUTTON_TEXT),
2000
);
})
.catch(console.log);
};
h2.append(button);
}
}
/**
* @param {string} uri
* @returns {boolean}
*/
function filterURI(uri) {
const uriObj = Spicetify.URI.from(uri);
if (
uriObj.type === Spicetify.URI.Type.ALBUM ||
uriObj.type === Spicetify.URI.Type.TRACK ||
uriObj.type === Spicetify.URI.Type.EPISODE
) {
return true;
}
return false;
}
})();