🔧 chore(spicetify): update custom app
This commit is contained in:
parent
78b5bc7880
commit
9a9148c5f7
6 changed files with 1172 additions and 848 deletions
|
@ -8,6 +8,7 @@ var library = (() => {
|
||||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||||
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
||||||
var __export = (target, all) => {
|
var __export = (target, all) => {
|
||||||
for (var name in all)
|
for (var name in all)
|
||||||
__defProp(target, name, { get: all[name], enumerable: true });
|
__defProp(target, name, { get: all[name], enumerable: true });
|
||||||
|
@ -21,6 +22,10 @@ var library = (() => {
|
||||||
return to;
|
return to;
|
||||||
};
|
};
|
||||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||||
|
var __publicField = (obj, key, value) => {
|
||||||
|
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
|
||||||
// src/extensions/collections_wrapper.ts
|
// src/extensions/collections_wrapper.ts
|
||||||
var collections_wrapper_exports = {};
|
var collections_wrapper_exports = {};
|
||||||
|
@ -77,7 +82,7 @@ var library = (() => {
|
||||||
var v4_default = v4;
|
var v4_default = v4;
|
||||||
|
|
||||||
// src/extensions/collections_wrapper.ts
|
// src/extensions/collections_wrapper.ts
|
||||||
var CollectionWrapper = class extends EventTarget {
|
var _CollectionsWrapper = class extends EventTarget {
|
||||||
_collections;
|
_collections;
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
@ -90,115 +95,189 @@ var library = (() => {
|
||||||
getCollection(uri) {
|
getCollection(uri) {
|
||||||
return this._collections.find((collection) => collection.uri === uri);
|
return this._collections.find((collection) => collection.uri === uri);
|
||||||
}
|
}
|
||||||
async requestAlbums({ sortOrder, textFilter }) {
|
async getCollectionContents(uri) {
|
||||||
|
const collection = this.getCollection(uri);
|
||||||
|
if (!collection)
|
||||||
|
throw new Error("Collection not found");
|
||||||
|
const items = this._collections.filter((collection2) => collection2.parentCollection === uri);
|
||||||
const albums = await Spicetify.Platform.LibraryAPI.getContents({
|
const albums = await Spicetify.Platform.LibraryAPI.getContents({
|
||||||
filters: ["0"],
|
filters: ["0"],
|
||||||
sortOrder,
|
|
||||||
textFilter,
|
|
||||||
offset: 0,
|
offset: 0,
|
||||||
limit: 9999
|
limit: 9999
|
||||||
});
|
});
|
||||||
return albums;
|
items.push(...albums.items.filter((album) => collection.items.includes(album.uri)));
|
||||||
|
return items;
|
||||||
}
|
}
|
||||||
async getCollectionItems(props) {
|
async getContents(props) {
|
||||||
const { collectionUri, textFilter, sortOrder, rootlist, limit = 9999, offset = 0 } = props;
|
const { collectionUri, offset, limit, textFilter } = props;
|
||||||
let collectionItems = this._collections;
|
let items = collectionUri ? await this.getCollectionContents(collectionUri) : this._collections;
|
||||||
let albumItems = [];
|
const openedCollectionName = collectionUri ? this.getCollection(collectionUri)?.name : void 0;
|
||||||
let unfilteredLength = this._collections.length;
|
|
||||||
let openedCollection = "";
|
|
||||||
if (collectionUri) {
|
|
||||||
const collection = this.getCollection(collectionUri);
|
|
||||||
const res = await this.requestAlbums({ sortOrder, textFilter });
|
|
||||||
const collectionSet = new Set(collection.items);
|
|
||||||
const commonElements = res.items.filter((item) => collectionSet.has(item.uri));
|
|
||||||
const collections = this._collections.filter((collection2) => collection2.parentCollection === collectionUri);
|
|
||||||
openedCollection = collection.name;
|
|
||||||
collectionItems = collections;
|
|
||||||
albumItems = commonElements;
|
|
||||||
unfilteredLength = collection.totalLength;
|
|
||||||
}
|
|
||||||
if (textFilter) {
|
if (textFilter) {
|
||||||
let regex = new RegExp("\\b" + textFilter, "i");
|
const regex = new RegExp(`\\b${textFilter}`, "i");
|
||||||
collectionItems = collectionItems.filter((item) => {
|
items = items.filter((collection) => regex.test(collection.name));
|
||||||
return regex.test(item.name);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
if (rootlist && !collectionUri) {
|
items = items.slice(offset, offset + limit);
|
||||||
const res = await this.requestAlbums({ sortOrder, textFilter });
|
return { items, totalLength: this._collections.length, offset, openedCollectionName };
|
||||||
albumItems = res.items;
|
}
|
||||||
if (!textFilter) {
|
async cleanCollections() {
|
||||||
const collectionSet = new Set(this._collections.map((collection) => collection.items).flat());
|
for (const collection of this._collections) {
|
||||||
const uncommonElements = res.items.filter((item) => !collectionSet.has(item.uri));
|
const boolArray = await Spicetify.Platform.LibraryAPI.contains(...collection.items);
|
||||||
collectionItems = this._collections.filter((collection) => !collection.parentCollection);
|
if (boolArray.includes(false)) {
|
||||||
albumItems = uncommonElements;
|
collection.items = collection.items.filter((_, i) => boolArray[i]);
|
||||||
unfilteredLength = this._collections.length + uncommonElements.length;
|
this.saveCollections();
|
||||||
|
Spicetify.showNotification("Album removed from collection");
|
||||||
|
this.syncCollection(collection.uri);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (offset > 0)
|
}
|
||||||
collectionItems = [];
|
async syncCollection(uri) {
|
||||||
return {
|
const collection = this.getCollection(uri);
|
||||||
openedCollection,
|
if (!collection)
|
||||||
items: [...collectionItems, ...albumItems.slice(offset, offset + limit)],
|
return;
|
||||||
totalLength: albumItems.length + collectionItems.length,
|
const { PlaylistAPI } = Spicetify.Platform;
|
||||||
unfilteredLength
|
if (!collection.syncedPlaylistUri)
|
||||||
};
|
return;
|
||||||
|
const playlist = await PlaylistAPI.getPlaylist(collection.syncedPlaylistUri);
|
||||||
|
const playlistTracks = playlist.contents.items.filter((t) => t.type === "track").map((t) => t.uri);
|
||||||
|
const collectionTracks = await this.getTracklist(uri);
|
||||||
|
const wanted = collectionTracks.filter((track) => !playlistTracks.includes(track));
|
||||||
|
const unwanted = playlistTracks.filter((track) => !collectionTracks.includes(track)).map((uri2) => ({ uri: uri2, uid: [] }));
|
||||||
|
if (wanted.length)
|
||||||
|
await PlaylistAPI.add(collection.syncedPlaylistUri, wanted, { before: "end" });
|
||||||
|
if (unwanted.length)
|
||||||
|
await PlaylistAPI.remove(collection.syncedPlaylistUri, unwanted);
|
||||||
|
}
|
||||||
|
unsyncCollection(uri) {
|
||||||
|
const collection = this.getCollection(uri);
|
||||||
|
if (!collection)
|
||||||
|
return;
|
||||||
|
collection.syncedPlaylistUri = void 0;
|
||||||
|
this.saveCollections();
|
||||||
|
}
|
||||||
|
async getTracklist(collectionUri) {
|
||||||
|
const collection = this.getCollection(collectionUri);
|
||||||
|
if (!collection)
|
||||||
|
return [];
|
||||||
|
return Promise.all(
|
||||||
|
collection.items.map(async (uri) => {
|
||||||
|
const album = await Spicetify.Platform.LibraryAPI.getAlbum(uri);
|
||||||
|
return album.items.map((t) => t.uri);
|
||||||
|
})
|
||||||
|
).then((tracks) => tracks.flat());
|
||||||
|
}
|
||||||
|
async convertToPlaylist(uri) {
|
||||||
|
const collection = this.getCollection(uri);
|
||||||
|
if (!collection)
|
||||||
|
return;
|
||||||
|
const { Platform, showNotification } = Spicetify;
|
||||||
|
const { RootlistAPI, PlaylistAPI } = Platform;
|
||||||
|
if (collection.syncedPlaylistUri) {
|
||||||
|
showNotification("Synced Playlist already exists", true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const playlistUri = await RootlistAPI.createPlaylist(collection.name, { before: "start" });
|
||||||
|
const items = await this.getTracklist(uri);
|
||||||
|
await PlaylistAPI.add(playlistUri, items, { before: "start" });
|
||||||
|
collection.syncedPlaylistUri = playlistUri;
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
showNotification("Failed to create playlist", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async createCollectionFromDiscog(artistUri) {
|
||||||
|
const [raw, info] = await Promise.all([
|
||||||
|
Spicetify.GraphQL.Request(Spicetify.GraphQL.Definitions.queryArtistDiscographyAlbums, {
|
||||||
|
uri: artistUri,
|
||||||
|
offset: 0,
|
||||||
|
limit: 50
|
||||||
|
}),
|
||||||
|
Spicetify.GraphQL.Request(Spicetify.GraphQL.Definitions.queryArtistOverview, {
|
||||||
|
uri: artistUri,
|
||||||
|
locale: Spicetify.Locale.getLocale(),
|
||||||
|
includePrerelease: false
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
const items = raw?.data?.artistUnion.discography.albums?.items;
|
||||||
|
const name = info?.data?.artistUnion.profile.name;
|
||||||
|
const image = info?.data?.artistUnion.visuals.avatarImage?.sources?.[0]?.url;
|
||||||
|
if (!name || !items?.length) {
|
||||||
|
Spicetify.showNotification("Artist not found or has no albums");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const collectionUri = this.createCollection(`${name} Albums`);
|
||||||
|
if (image)
|
||||||
|
this.setCollectionImage(collectionUri, image);
|
||||||
|
for (const album of items) {
|
||||||
|
this.addAlbumToCollection(collectionUri, album.releases.items[0].uri);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
createCollection(name, parentCollection = "") {
|
createCollection(name, parentCollection = "") {
|
||||||
const uri = v4_default();
|
const id = v4_default();
|
||||||
const collection = {
|
this._collections.push({
|
||||||
type: "collection",
|
type: "collection",
|
||||||
uri,
|
uri: id,
|
||||||
name,
|
name,
|
||||||
items: [],
|
items: [],
|
||||||
totalLength: 0,
|
addedAt: new Date(),
|
||||||
imgUrl: "",
|
lastPlayedAt: new Date(),
|
||||||
parentCollection
|
parentCollection
|
||||||
};
|
});
|
||||||
this._collections.push(collection);
|
|
||||||
this.saveCollections();
|
this.saveCollections();
|
||||||
Spicetify.showNotification("Collection created");
|
Spicetify.showNotification("Collection created");
|
||||||
|
return id;
|
||||||
}
|
}
|
||||||
deleteCollection(uri) {
|
deleteCollection(uri) {
|
||||||
this._collections = this._collections.filter((collection) => collection.uri !== uri);
|
this._collections = this._collections.filter((collection) => collection.uri !== uri);
|
||||||
this.saveCollections();
|
this.saveCollections();
|
||||||
Spicetify.showNotification("Collection deleted");
|
Spicetify.showNotification("Collection deleted");
|
||||||
}
|
}
|
||||||
|
deleteCollectionAndAlbums(uri) {
|
||||||
|
const collection = this.getCollection(uri);
|
||||||
|
if (!collection)
|
||||||
|
return;
|
||||||
|
for (const album of collection.items) {
|
||||||
|
Spicetify.Platform.LibraryAPI.remove({ uris: [album] });
|
||||||
|
}
|
||||||
|
this.deleteCollection(uri);
|
||||||
|
}
|
||||||
async addAlbumToCollection(collectionUri, albumUri) {
|
async addAlbumToCollection(collectionUri, albumUri) {
|
||||||
const collection = this.getCollection(collectionUri);
|
const collection = this.getCollection(collectionUri);
|
||||||
if (!collection)
|
if (!collection)
|
||||||
return;
|
return;
|
||||||
|
await Spicetify.Platform.LibraryAPI.add({ uris: [albumUri] });
|
||||||
collection.items.push(albumUri);
|
collection.items.push(albumUri);
|
||||||
collection.totalLength++;
|
|
||||||
this.saveCollections();
|
this.saveCollections();
|
||||||
Spicetify.showNotification("Album added to collection");
|
Spicetify.showNotification("Album added to collection");
|
||||||
|
this.syncCollection(collectionUri);
|
||||||
}
|
}
|
||||||
removeAlbumFromCollection(collectionUri, albumUri) {
|
removeAlbumFromCollection(collectionUri, albumUri) {
|
||||||
const collection = this.getCollection(collectionUri);
|
const collection = this.getCollection(collectionUri);
|
||||||
if (!collection)
|
if (!collection)
|
||||||
return;
|
return;
|
||||||
collection.items = collection.items.filter((item) => item !== albumUri);
|
collection.items = collection.items.filter((item) => item !== albumUri);
|
||||||
collection.totalLength--;
|
|
||||||
this.saveCollections();
|
this.saveCollections();
|
||||||
Spicetify.showNotification("Album removed from collection");
|
Spicetify.showNotification("Album removed from collection");
|
||||||
|
this.syncCollection(collectionUri);
|
||||||
}
|
}
|
||||||
getCollectionsWithAlbum(albumUri) {
|
getCollectionsWithAlbum(albumUri) {
|
||||||
return this._collections.filter((collection) => {
|
return this._collections.filter((collection) => {
|
||||||
return collection.items.some((item) => item === albumUri);
|
return collection.items.some((item) => item === albumUri);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
renameCollection(uri, newName) {
|
renameCollection(uri, name) {
|
||||||
const collection = this.getCollection(uri);
|
const collection = this.getCollection(uri);
|
||||||
if (!collection)
|
if (!collection)
|
||||||
return;
|
return;
|
||||||
collection.name = newName;
|
collection.name = name;
|
||||||
this.saveCollections();
|
this.saveCollections();
|
||||||
Spicetify.showNotification("Collection renamed");
|
Spicetify.showNotification("Collection renamed");
|
||||||
}
|
}
|
||||||
setCollectionImage(uri, imgUrl) {
|
setCollectionImage(uri, url) {
|
||||||
const collection = this.getCollection(uri);
|
const collection = this.getCollection(uri);
|
||||||
if (!collection)
|
if (!collection)
|
||||||
return;
|
return;
|
||||||
collection.imgUrl = imgUrl;
|
collection.image = url;
|
||||||
this.saveCollections();
|
this.saveCollections();
|
||||||
Spicetify.showNotification("Collection image set");
|
Spicetify.showNotification("Collection image set");
|
||||||
}
|
}
|
||||||
|
@ -206,12 +285,15 @@ var library = (() => {
|
||||||
const collection = this.getCollection(uri);
|
const collection = this.getCollection(uri);
|
||||||
if (!collection)
|
if (!collection)
|
||||||
return;
|
return;
|
||||||
collection.imgUrl = "";
|
collection.image = void 0;
|
||||||
this.saveCollections();
|
this.saveCollections();
|
||||||
Spicetify.showNotification("Collection image removed");
|
Spicetify.showNotification("Collection image removed");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var collections_wrapper_default = CollectionWrapper;
|
var CollectionsWrapper = _CollectionsWrapper;
|
||||||
|
__publicField(CollectionsWrapper, "INSTANCE", new _CollectionsWrapper());
|
||||||
|
window.CollectionsWrapper = CollectionsWrapper.INSTANCE;
|
||||||
|
var collections_wrapper_default = CollectionsWrapper;
|
||||||
return __toCommonJS(collections_wrapper_exports);
|
return __toCommonJS(collections_wrapper_exports);
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|
|
@ -285,7 +285,9 @@ var library = (() => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
var ToggleFiltersButton = () => {
|
var ToggleFiltersButton = () => {
|
||||||
const [direction, setDirection] = import_react3.default.useState(document.body.classList.contains("show-ylx-filters") ? "up" : "down");
|
const [direction, setDirection] = import_react3.default.useState(
|
||||||
|
document.body.classList.contains("show-ylx-filters") ? "up" : "down"
|
||||||
|
);
|
||||||
const { ButtonTertiary } = Spicetify.ReactComponent;
|
const { ButtonTertiary } = Spicetify.ReactComponent;
|
||||||
const toggleDirection = () => {
|
const toggleDirection = () => {
|
||||||
if (direction === "down") {
|
if (direction === "down") {
|
||||||
|
@ -332,31 +334,207 @@ var library = (() => {
|
||||||
};
|
};
|
||||||
var collapse_button_default = CollapseButton;
|
var collapse_button_default = CollapseButton;
|
||||||
|
|
||||||
// src/components/expand_button.tsx
|
// src/components/album_menu_item.tsx
|
||||||
|
var import_react8 = __toESM(require_react());
|
||||||
|
|
||||||
|
// src/components/leading_icon.tsx
|
||||||
var import_react5 = __toESM(require_react());
|
var import_react5 = __toESM(require_react());
|
||||||
var expandLibrary = () => {
|
var LeadingIcon = ({ path }) => {
|
||||||
Spicetify.Platform.LocalStorageAPI.setItem("ylx-sidebar-state", 0);
|
return /* @__PURE__ */ import_react5.default.createElement(Spicetify.ReactComponent.IconComponent, {
|
||||||
};
|
|
||||||
var ExpandIcon = () => {
|
|
||||||
const { IconComponent } = Spicetify.ReactComponent;
|
|
||||||
return /* @__PURE__ */ import_react5.default.createElement(IconComponent, {
|
|
||||||
semanticColor: "textSubdued",
|
semanticColor: "textSubdued",
|
||||||
dangerouslySetInnerHTML: {
|
dangerouslySetInnerHTML: {
|
||||||
__html: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" ><path d="M7.19 1A.749.749 0 0 1 8.47.47L16 7.99l-7.53 7.521a.75.75 0 0 1-1.234-.815.75.75 0 0 1 .174-.243l5.72-5.714H.75a.75.75 0 1 1 0-1.498h12.38L7.41 1.529a.749.749 0 0 1-.22-.53z"></path></svg>'
|
__html: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">${path}</svg>`
|
||||||
},
|
},
|
||||||
iconSize: 16
|
iconSize: 16
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
var ExpandButton = () => {
|
var leading_icon_default = LeadingIcon;
|
||||||
const { ButtonTertiary } = Spicetify.ReactComponent;
|
|
||||||
return /* @__PURE__ */ import_react5.default.createElement(ButtonTertiary, {
|
// src/components/text_input_dialog.tsx
|
||||||
buttonSize: "sm",
|
var import_react6 = __toESM(require_react());
|
||||||
"aria-label": "Show Filters",
|
var TextInputDialog = (props) => {
|
||||||
iconOnly: ExpandIcon,
|
const { def, placeholder, onSave } = props;
|
||||||
onClick: expandLibrary
|
const [value, setValue] = import_react6.default.useState(def || "");
|
||||||
|
const onSubmit = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
Spicetify.PopupModal.hide();
|
||||||
|
onSave(value);
|
||||||
|
};
|
||||||
|
return /* @__PURE__ */ import_react6.default.createElement(import_react6.default.Fragment, null, /* @__PURE__ */ import_react6.default.createElement("form", {
|
||||||
|
className: "text-input-form",
|
||||||
|
onSubmit
|
||||||
|
}, /* @__PURE__ */ import_react6.default.createElement("label", {
|
||||||
|
className: "text-input-wrapper"
|
||||||
|
}, /* @__PURE__ */ import_react6.default.createElement("input", {
|
||||||
|
className: "text-input",
|
||||||
|
type: "text",
|
||||||
|
value,
|
||||||
|
placeholder,
|
||||||
|
onChange: (e) => setValue(e.target.value)
|
||||||
|
})), /* @__PURE__ */ import_react6.default.createElement("button", {
|
||||||
|
type: "submit",
|
||||||
|
"data-encore-id": "buttonPrimary",
|
||||||
|
className: "Button-sc-qlcn5g-0 Button-small-buttonPrimary"
|
||||||
|
}, /* @__PURE__ */ import_react6.default.createElement("span", {
|
||||||
|
className: "ButtonInner-sc-14ud5tc-0 ButtonInner-small encore-bright-accent-set"
|
||||||
|
}, "Save"))));
|
||||||
|
};
|
||||||
|
var text_input_dialog_default = TextInputDialog;
|
||||||
|
|
||||||
|
// src/components/searchbar.tsx
|
||||||
|
var import_react7 = __toESM(require_react());
|
||||||
|
var SearchBar = (props) => {
|
||||||
|
const { setSearch, placeholder } = props;
|
||||||
|
const handleChange = (e) => {
|
||||||
|
setSearch(e.target.value);
|
||||||
|
};
|
||||||
|
return /* @__PURE__ */ import_react7.default.createElement("div", {
|
||||||
|
className: "x-filterBox-filterInputContainer x-filterBox-expandedOrHasFilter",
|
||||||
|
role: "search"
|
||||||
|
}, /* @__PURE__ */ import_react7.default.createElement("input", {
|
||||||
|
type: "text",
|
||||||
|
className: "x-filterBox-filterInput",
|
||||||
|
role: "searchbox",
|
||||||
|
maxLength: 80,
|
||||||
|
autoCorrect: "off",
|
||||||
|
autoCapitalize: "off",
|
||||||
|
spellCheck: "false",
|
||||||
|
placeholder: `Search ${placeholder}`,
|
||||||
|
"aria-hidden": "false",
|
||||||
|
onChange: handleChange
|
||||||
|
}), /* @__PURE__ */ import_react7.default.createElement("div", {
|
||||||
|
className: "x-filterBox-overlay"
|
||||||
|
}, /* @__PURE__ */ import_react7.default.createElement("span", {
|
||||||
|
className: "x-filterBox-searchIconContainer"
|
||||||
|
}, /* @__PURE__ */ import_react7.default.createElement("svg", {
|
||||||
|
"data-encore-id": "icon",
|
||||||
|
role: "img",
|
||||||
|
"aria-hidden": "true",
|
||||||
|
className: "Svg-sc-ytk21e-0 Svg-img-icon-small x-filterBox-searchIcon",
|
||||||
|
viewBox: "0 0 16 16"
|
||||||
|
}, /* @__PURE__ */ import_react7.default.createElement("path", {
|
||||||
|
d: "M7 1.75a5.25 5.25 0 1 0 0 10.5 5.25 5.25 0 0 0 0-10.5zM.25 7a6.75 6.75 0 1 1 12.096 4.12l3.184 3.185a.75.75 0 1 1-1.06 1.06L11.304 12.2A6.75 6.75 0 0 1 .25 7z"
|
||||||
|
})))), /* @__PURE__ */ import_react7.default.createElement("button", {
|
||||||
|
className: "x-filterBox-expandButton",
|
||||||
|
"aria-hidden": "false",
|
||||||
|
"aria-label": "Search Playlists",
|
||||||
|
type: "button"
|
||||||
|
}, /* @__PURE__ */ import_react7.default.createElement("svg", {
|
||||||
|
"data-encore-id": "icon",
|
||||||
|
role: "img",
|
||||||
|
"aria-hidden": "true",
|
||||||
|
className: "Svg-sc-ytk21e-0 Svg-img-icon-small x-filterBox-searchIcon",
|
||||||
|
viewBox: "0 0 16 16"
|
||||||
|
}, /* @__PURE__ */ import_react7.default.createElement("path", {
|
||||||
|
d: "M7 1.75a5.25 5.25 0 1 0 0 10.5 5.25 5.25 0 0 0 0-10.5zM.25 7a6.75 6.75 0 1 1 12.096 4.12l3.184 3.185a.75.75 0 1 1-1.06 1.06L11.304 12.2A6.75 6.75 0 0 1 .25 7z"
|
||||||
|
}))));
|
||||||
|
};
|
||||||
|
var searchbar_default = SearchBar;
|
||||||
|
|
||||||
|
// src/components/album_menu_item.tsx
|
||||||
|
var createCollection = () => {
|
||||||
|
const onSave = (value) => {
|
||||||
|
CollectionsWrapper.createCollection(value);
|
||||||
|
};
|
||||||
|
Spicetify.PopupModal.display({
|
||||||
|
title: "Create Collection",
|
||||||
|
content: /* @__PURE__ */ import_react8.default.createElement(text_input_dialog_default, {
|
||||||
|
def: "New Collection",
|
||||||
|
placeholder: "Collection Name",
|
||||||
|
onSave
|
||||||
|
})
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
var expand_button_default = ExpandButton;
|
var CollectionSearchMenu = () => {
|
||||||
|
const { MenuItem } = Spicetify.ReactComponent;
|
||||||
|
const { SVGIcons } = Spicetify;
|
||||||
|
const [textFilter, setTextFilter] = import_react8.default.useState("");
|
||||||
|
const [collections, setCollections] = import_react8.default.useState(null);
|
||||||
|
const context = import_react8.default.useContext(Spicetify.ContextMenuV2._context);
|
||||||
|
const uri = context?.props?.uri;
|
||||||
|
import_react8.default.useEffect(() => {
|
||||||
|
const fetchCollections = async () => {
|
||||||
|
setCollections(await CollectionsWrapper.getContents({ textFilter, limit: 20, offset: 0 }));
|
||||||
|
};
|
||||||
|
fetchCollections();
|
||||||
|
}, [textFilter]);
|
||||||
|
if (!collections)
|
||||||
|
return /* @__PURE__ */ import_react8.default.createElement(import_react8.default.Fragment, null);
|
||||||
|
const addToCollection = (collectionUri) => {
|
||||||
|
CollectionsWrapper.addAlbumToCollection(collectionUri, uri);
|
||||||
|
};
|
||||||
|
const activeCollections = CollectionsWrapper.getCollectionsWithAlbum(uri);
|
||||||
|
const hasCollections = activeCollections.length > 0;
|
||||||
|
const removeFromCollections = () => {
|
||||||
|
for (const collection of activeCollections) {
|
||||||
|
CollectionsWrapper.removeAlbumFromCollection(collection.uri, uri);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const allCollectionsLength = collections.totalLength;
|
||||||
|
const menuItems = collections.items.map((collection, index) => {
|
||||||
|
return /* @__PURE__ */ import_react8.default.createElement(MenuItem, {
|
||||||
|
key: collection.uri,
|
||||||
|
onClick: () => {
|
||||||
|
addToCollection(collection.uri);
|
||||||
|
},
|
||||||
|
divider: index === 0 ? "before" : void 0
|
||||||
|
}, collection.name);
|
||||||
|
});
|
||||||
|
const menuLength = allCollectionsLength + (hasCollections ? 1 : 0);
|
||||||
|
return /* @__PURE__ */ import_react8.default.createElement("div", {
|
||||||
|
className: "main-contextMenu-filterPlaylistSearchContainer",
|
||||||
|
style: { "--context-menu-submenu-length": `${menuLength}` }
|
||||||
|
}, /* @__PURE__ */ import_react8.default.createElement("li", {
|
||||||
|
role: "presentation",
|
||||||
|
className: "main-contextMenu-filterPlaylistSearch"
|
||||||
|
}, /* @__PURE__ */ import_react8.default.createElement("div", {
|
||||||
|
role: "menuitem"
|
||||||
|
}, /* @__PURE__ */ import_react8.default.createElement(searchbar_default, {
|
||||||
|
setSearch: setTextFilter,
|
||||||
|
placeholder: "collections"
|
||||||
|
}))), /* @__PURE__ */ import_react8.default.createElement(MenuItem, {
|
||||||
|
key: "new-collection",
|
||||||
|
leadingIcon: /* @__PURE__ */ import_react8.default.createElement(leading_icon_default, {
|
||||||
|
path: SVGIcons.plus2px
|
||||||
|
}),
|
||||||
|
onClick: createCollection
|
||||||
|
}, "Create collection"), hasCollections && /* @__PURE__ */ import_react8.default.createElement(MenuItem, {
|
||||||
|
key: "remove-collection",
|
||||||
|
leadingIcon: /* @__PURE__ */ import_react8.default.createElement(leading_icon_default, {
|
||||||
|
path: SVGIcons.minus
|
||||||
|
}),
|
||||||
|
onClick: removeFromCollections
|
||||||
|
}, "Remove from all"), menuItems);
|
||||||
|
};
|
||||||
|
var AlbumMenuItem = () => {
|
||||||
|
const { MenuSubMenuItem } = Spicetify.ReactComponent;
|
||||||
|
const { SVGIcons } = Spicetify;
|
||||||
|
return /* @__PURE__ */ import_react8.default.createElement(MenuSubMenuItem, {
|
||||||
|
displayText: "Add to collection",
|
||||||
|
divider: "after",
|
||||||
|
leadingIcon: /* @__PURE__ */ import_react8.default.createElement(leading_icon_default, {
|
||||||
|
path: SVGIcons.plus2px
|
||||||
|
})
|
||||||
|
}, /* @__PURE__ */ import_react8.default.createElement(CollectionSearchMenu, null));
|
||||||
|
};
|
||||||
|
var album_menu_item_default = AlbumMenuItem;
|
||||||
|
|
||||||
|
// src/components/artist_menu_item.tsx
|
||||||
|
var import_react9 = __toESM(require_react());
|
||||||
|
var ArtistMenuItem = () => {
|
||||||
|
const { MenuItem } = Spicetify.ReactComponent;
|
||||||
|
const { SVGIcons } = Spicetify;
|
||||||
|
const context = import_react9.default.useContext(Spicetify.ContextMenuV2._context);
|
||||||
|
const uri = context?.props?.uri;
|
||||||
|
return /* @__PURE__ */ import_react9.default.createElement(MenuItem, {
|
||||||
|
divider: "after",
|
||||||
|
leadingIcon: /* @__PURE__ */ import_react9.default.createElement(leading_icon_default, {
|
||||||
|
path: SVGIcons.plus2px
|
||||||
|
}),
|
||||||
|
onClick: () => CollectionsWrapper.createCollectionFromDiscog(uri)
|
||||||
|
}, "Create Discog Collection");
|
||||||
|
};
|
||||||
|
var artist_menu_item_default = ArtistMenuItem;
|
||||||
|
|
||||||
// ../node_modules/uuid/dist/esm-browser/rng.js
|
// ../node_modules/uuid/dist/esm-browser/rng.js
|
||||||
var getRandomValues;
|
var getRandomValues;
|
||||||
|
@ -407,7 +585,7 @@ var library = (() => {
|
||||||
var v4_default = v4;
|
var v4_default = v4;
|
||||||
|
|
||||||
// src/extensions/collections_wrapper.ts
|
// src/extensions/collections_wrapper.ts
|
||||||
var CollectionWrapper = class extends EventTarget {
|
var _CollectionsWrapper = class extends EventTarget {
|
||||||
_collections;
|
_collections;
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
@ -420,115 +598,189 @@ var library = (() => {
|
||||||
getCollection(uri) {
|
getCollection(uri) {
|
||||||
return this._collections.find((collection) => collection.uri === uri);
|
return this._collections.find((collection) => collection.uri === uri);
|
||||||
}
|
}
|
||||||
async requestAlbums({ sortOrder, textFilter }) {
|
async getCollectionContents(uri) {
|
||||||
|
const collection = this.getCollection(uri);
|
||||||
|
if (!collection)
|
||||||
|
throw new Error("Collection not found");
|
||||||
|
const items = this._collections.filter((collection2) => collection2.parentCollection === uri);
|
||||||
const albums = await Spicetify.Platform.LibraryAPI.getContents({
|
const albums = await Spicetify.Platform.LibraryAPI.getContents({
|
||||||
filters: ["0"],
|
filters: ["0"],
|
||||||
sortOrder,
|
|
||||||
textFilter,
|
|
||||||
offset: 0,
|
offset: 0,
|
||||||
limit: 9999
|
limit: 9999
|
||||||
});
|
});
|
||||||
return albums;
|
items.push(...albums.items.filter((album) => collection.items.includes(album.uri)));
|
||||||
|
return items;
|
||||||
}
|
}
|
||||||
async getCollectionItems(props) {
|
async getContents(props) {
|
||||||
const { collectionUri, textFilter, sortOrder, rootlist, limit = 9999, offset = 0 } = props;
|
const { collectionUri, offset, limit, textFilter } = props;
|
||||||
let collectionItems = this._collections;
|
let items = collectionUri ? await this.getCollectionContents(collectionUri) : this._collections;
|
||||||
let albumItems = [];
|
const openedCollectionName = collectionUri ? this.getCollection(collectionUri)?.name : void 0;
|
||||||
let unfilteredLength = this._collections.length;
|
|
||||||
let openedCollection = "";
|
|
||||||
if (collectionUri) {
|
|
||||||
const collection = this.getCollection(collectionUri);
|
|
||||||
const res = await this.requestAlbums({ sortOrder, textFilter });
|
|
||||||
const collectionSet = new Set(collection.items);
|
|
||||||
const commonElements = res.items.filter((item) => collectionSet.has(item.uri));
|
|
||||||
const collections = this._collections.filter((collection2) => collection2.parentCollection === collectionUri);
|
|
||||||
openedCollection = collection.name;
|
|
||||||
collectionItems = collections;
|
|
||||||
albumItems = commonElements;
|
|
||||||
unfilteredLength = collection.totalLength;
|
|
||||||
}
|
|
||||||
if (textFilter) {
|
if (textFilter) {
|
||||||
let regex = new RegExp("\\b" + textFilter, "i");
|
const regex = new RegExp(`\\b${textFilter}`, "i");
|
||||||
collectionItems = collectionItems.filter((item) => {
|
items = items.filter((collection) => regex.test(collection.name));
|
||||||
return regex.test(item.name);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
if (rootlist && !collectionUri) {
|
items = items.slice(offset, offset + limit);
|
||||||
const res = await this.requestAlbums({ sortOrder, textFilter });
|
return { items, totalLength: this._collections.length, offset, openedCollectionName };
|
||||||
albumItems = res.items;
|
}
|
||||||
if (!textFilter) {
|
async cleanCollections() {
|
||||||
const collectionSet = new Set(this._collections.map((collection) => collection.items).flat());
|
for (const collection of this._collections) {
|
||||||
const uncommonElements = res.items.filter((item) => !collectionSet.has(item.uri));
|
const boolArray = await Spicetify.Platform.LibraryAPI.contains(...collection.items);
|
||||||
collectionItems = this._collections.filter((collection) => !collection.parentCollection);
|
if (boolArray.includes(false)) {
|
||||||
albumItems = uncommonElements;
|
collection.items = collection.items.filter((_, i) => boolArray[i]);
|
||||||
unfilteredLength = this._collections.length + uncommonElements.length;
|
this.saveCollections();
|
||||||
|
Spicetify.showNotification("Album removed from collection");
|
||||||
|
this.syncCollection(collection.uri);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (offset > 0)
|
}
|
||||||
collectionItems = [];
|
async syncCollection(uri) {
|
||||||
return {
|
const collection = this.getCollection(uri);
|
||||||
openedCollection,
|
if (!collection)
|
||||||
items: [...collectionItems, ...albumItems.slice(offset, offset + limit)],
|
return;
|
||||||
totalLength: albumItems.length + collectionItems.length,
|
const { PlaylistAPI } = Spicetify.Platform;
|
||||||
unfilteredLength
|
if (!collection.syncedPlaylistUri)
|
||||||
};
|
return;
|
||||||
|
const playlist = await PlaylistAPI.getPlaylist(collection.syncedPlaylistUri);
|
||||||
|
const playlistTracks = playlist.contents.items.filter((t) => t.type === "track").map((t) => t.uri);
|
||||||
|
const collectionTracks = await this.getTracklist(uri);
|
||||||
|
const wanted = collectionTracks.filter((track) => !playlistTracks.includes(track));
|
||||||
|
const unwanted = playlistTracks.filter((track) => !collectionTracks.includes(track)).map((uri2) => ({ uri: uri2, uid: [] }));
|
||||||
|
if (wanted.length)
|
||||||
|
await PlaylistAPI.add(collection.syncedPlaylistUri, wanted, { before: "end" });
|
||||||
|
if (unwanted.length)
|
||||||
|
await PlaylistAPI.remove(collection.syncedPlaylistUri, unwanted);
|
||||||
|
}
|
||||||
|
unsyncCollection(uri) {
|
||||||
|
const collection = this.getCollection(uri);
|
||||||
|
if (!collection)
|
||||||
|
return;
|
||||||
|
collection.syncedPlaylistUri = void 0;
|
||||||
|
this.saveCollections();
|
||||||
|
}
|
||||||
|
async getTracklist(collectionUri) {
|
||||||
|
const collection = this.getCollection(collectionUri);
|
||||||
|
if (!collection)
|
||||||
|
return [];
|
||||||
|
return Promise.all(
|
||||||
|
collection.items.map(async (uri) => {
|
||||||
|
const album = await Spicetify.Platform.LibraryAPI.getAlbum(uri);
|
||||||
|
return album.items.map((t) => t.uri);
|
||||||
|
})
|
||||||
|
).then((tracks) => tracks.flat());
|
||||||
|
}
|
||||||
|
async convertToPlaylist(uri) {
|
||||||
|
const collection = this.getCollection(uri);
|
||||||
|
if (!collection)
|
||||||
|
return;
|
||||||
|
const { Platform, showNotification } = Spicetify;
|
||||||
|
const { RootlistAPI, PlaylistAPI } = Platform;
|
||||||
|
if (collection.syncedPlaylistUri) {
|
||||||
|
showNotification("Synced Playlist already exists", true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const playlistUri = await RootlistAPI.createPlaylist(collection.name, { before: "start" });
|
||||||
|
const items = await this.getTracklist(uri);
|
||||||
|
await PlaylistAPI.add(playlistUri, items, { before: "start" });
|
||||||
|
collection.syncedPlaylistUri = playlistUri;
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
showNotification("Failed to create playlist", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async createCollectionFromDiscog(artistUri) {
|
||||||
|
const [raw, info] = await Promise.all([
|
||||||
|
Spicetify.GraphQL.Request(Spicetify.GraphQL.Definitions.queryArtistDiscographyAlbums, {
|
||||||
|
uri: artistUri,
|
||||||
|
offset: 0,
|
||||||
|
limit: 50
|
||||||
|
}),
|
||||||
|
Spicetify.GraphQL.Request(Spicetify.GraphQL.Definitions.queryArtistOverview, {
|
||||||
|
uri: artistUri,
|
||||||
|
locale: Spicetify.Locale.getLocale(),
|
||||||
|
includePrerelease: false
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
const items = raw?.data?.artistUnion.discography.albums?.items;
|
||||||
|
const name = info?.data?.artistUnion.profile.name;
|
||||||
|
const image = info?.data?.artistUnion.visuals.avatarImage?.sources?.[0]?.url;
|
||||||
|
if (!name || !items?.length) {
|
||||||
|
Spicetify.showNotification("Artist not found or has no albums");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const collectionUri = this.createCollection(`${name} Albums`);
|
||||||
|
if (image)
|
||||||
|
this.setCollectionImage(collectionUri, image);
|
||||||
|
for (const album of items) {
|
||||||
|
this.addAlbumToCollection(collectionUri, album.releases.items[0].uri);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
createCollection(name, parentCollection = "") {
|
createCollection(name, parentCollection = "") {
|
||||||
const uri = v4_default();
|
const id = v4_default();
|
||||||
const collection = {
|
this._collections.push({
|
||||||
type: "collection",
|
type: "collection",
|
||||||
uri,
|
uri: id,
|
||||||
name,
|
name,
|
||||||
items: [],
|
items: [],
|
||||||
totalLength: 0,
|
addedAt: new Date(),
|
||||||
imgUrl: "",
|
lastPlayedAt: new Date(),
|
||||||
parentCollection
|
parentCollection
|
||||||
};
|
});
|
||||||
this._collections.push(collection);
|
|
||||||
this.saveCollections();
|
this.saveCollections();
|
||||||
Spicetify.showNotification("Collection created");
|
Spicetify.showNotification("Collection created");
|
||||||
|
return id;
|
||||||
}
|
}
|
||||||
deleteCollection(uri) {
|
deleteCollection(uri) {
|
||||||
this._collections = this._collections.filter((collection) => collection.uri !== uri);
|
this._collections = this._collections.filter((collection) => collection.uri !== uri);
|
||||||
this.saveCollections();
|
this.saveCollections();
|
||||||
Spicetify.showNotification("Collection deleted");
|
Spicetify.showNotification("Collection deleted");
|
||||||
}
|
}
|
||||||
|
deleteCollectionAndAlbums(uri) {
|
||||||
|
const collection = this.getCollection(uri);
|
||||||
|
if (!collection)
|
||||||
|
return;
|
||||||
|
for (const album of collection.items) {
|
||||||
|
Spicetify.Platform.LibraryAPI.remove({ uris: [album] });
|
||||||
|
}
|
||||||
|
this.deleteCollection(uri);
|
||||||
|
}
|
||||||
async addAlbumToCollection(collectionUri, albumUri) {
|
async addAlbumToCollection(collectionUri, albumUri) {
|
||||||
const collection = this.getCollection(collectionUri);
|
const collection = this.getCollection(collectionUri);
|
||||||
if (!collection)
|
if (!collection)
|
||||||
return;
|
return;
|
||||||
|
await Spicetify.Platform.LibraryAPI.add({ uris: [albumUri] });
|
||||||
collection.items.push(albumUri);
|
collection.items.push(albumUri);
|
||||||
collection.totalLength++;
|
|
||||||
this.saveCollections();
|
this.saveCollections();
|
||||||
Spicetify.showNotification("Album added to collection");
|
Spicetify.showNotification("Album added to collection");
|
||||||
|
this.syncCollection(collectionUri);
|
||||||
}
|
}
|
||||||
removeAlbumFromCollection(collectionUri, albumUri) {
|
removeAlbumFromCollection(collectionUri, albumUri) {
|
||||||
const collection = this.getCollection(collectionUri);
|
const collection = this.getCollection(collectionUri);
|
||||||
if (!collection)
|
if (!collection)
|
||||||
return;
|
return;
|
||||||
collection.items = collection.items.filter((item) => item !== albumUri);
|
collection.items = collection.items.filter((item) => item !== albumUri);
|
||||||
collection.totalLength--;
|
|
||||||
this.saveCollections();
|
this.saveCollections();
|
||||||
Spicetify.showNotification("Album removed from collection");
|
Spicetify.showNotification("Album removed from collection");
|
||||||
|
this.syncCollection(collectionUri);
|
||||||
}
|
}
|
||||||
getCollectionsWithAlbum(albumUri) {
|
getCollectionsWithAlbum(albumUri) {
|
||||||
return this._collections.filter((collection) => {
|
return this._collections.filter((collection) => {
|
||||||
return collection.items.some((item) => item === albumUri);
|
return collection.items.some((item) => item === albumUri);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
renameCollection(uri, newName) {
|
renameCollection(uri, name) {
|
||||||
const collection = this.getCollection(uri);
|
const collection = this.getCollection(uri);
|
||||||
if (!collection)
|
if (!collection)
|
||||||
return;
|
return;
|
||||||
collection.name = newName;
|
collection.name = name;
|
||||||
this.saveCollections();
|
this.saveCollections();
|
||||||
Spicetify.showNotification("Collection renamed");
|
Spicetify.showNotification("Collection renamed");
|
||||||
}
|
}
|
||||||
setCollectionImage(uri, imgUrl) {
|
setCollectionImage(uri, url) {
|
||||||
const collection = this.getCollection(uri);
|
const collection = this.getCollection(uri);
|
||||||
if (!collection)
|
if (!collection)
|
||||||
return;
|
return;
|
||||||
collection.imgUrl = imgUrl;
|
collection.image = url;
|
||||||
this.saveCollections();
|
this.saveCollections();
|
||||||
Spicetify.showNotification("Collection image set");
|
Spicetify.showNotification("Collection image set");
|
||||||
}
|
}
|
||||||
|
@ -536,201 +788,17 @@ var library = (() => {
|
||||||
const collection = this.getCollection(uri);
|
const collection = this.getCollection(uri);
|
||||||
if (!collection)
|
if (!collection)
|
||||||
return;
|
return;
|
||||||
collection.imgUrl = "";
|
collection.image = void 0;
|
||||||
this.saveCollections();
|
this.saveCollections();
|
||||||
Spicetify.showNotification("Collection image removed");
|
Spicetify.showNotification("Collection image removed");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var collections_wrapper_default = CollectionWrapper;
|
var CollectionsWrapper2 = _CollectionsWrapper;
|
||||||
|
__publicField(CollectionsWrapper2, "INSTANCE", new _CollectionsWrapper());
|
||||||
// src/components/album_menu_item.tsx
|
window.CollectionsWrapper = CollectionsWrapper2.INSTANCE;
|
||||||
var import_react9 = __toESM(require_react());
|
|
||||||
|
|
||||||
// src/components/leading_icon.tsx
|
|
||||||
var import_react6 = __toESM(require_react());
|
|
||||||
var LeadingIcon = ({ path }) => {
|
|
||||||
return /* @__PURE__ */ import_react6.default.createElement(Spicetify.ReactComponent.IconComponent, {
|
|
||||||
semanticColor: "textSubdued",
|
|
||||||
dangerouslySetInnerHTML: {
|
|
||||||
__html: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">${path}</svg>`
|
|
||||||
},
|
|
||||||
iconSize: 16
|
|
||||||
});
|
|
||||||
};
|
|
||||||
var leading_icon_default = LeadingIcon;
|
|
||||||
|
|
||||||
// src/components/text_input_dialog.tsx
|
|
||||||
var import_react7 = __toESM(require_react());
|
|
||||||
var TextInputDialog = (props) => {
|
|
||||||
const { ButtonPrimary } = Spicetify.ReactComponent;
|
|
||||||
const { def, placeholder, onSave } = props;
|
|
||||||
const [value, setValue] = import_react7.default.useState(def);
|
|
||||||
const onSubmit = (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
Spicetify.PopupModal.hide();
|
|
||||||
onSave(value);
|
|
||||||
};
|
|
||||||
return /* @__PURE__ */ import_react7.default.createElement(import_react7.default.Fragment, null, /* @__PURE__ */ import_react7.default.createElement("form", {
|
|
||||||
className: "text-input-form",
|
|
||||||
onSubmit
|
|
||||||
}, /* @__PURE__ */ import_react7.default.createElement("label", {
|
|
||||||
className: "text-input-wrapper"
|
|
||||||
}, /* @__PURE__ */ import_react7.default.createElement("input", {
|
|
||||||
className: "text-input",
|
|
||||||
type: "text",
|
|
||||||
value,
|
|
||||||
placeholder,
|
|
||||||
onChange: (e) => setValue(e.target.value)
|
|
||||||
})), /* @__PURE__ */ import_react7.default.createElement("button", {
|
|
||||||
type: "submit",
|
|
||||||
"data-encore-id": "buttonPrimary",
|
|
||||||
className: "Button-sc-qlcn5g-0 Button-small-buttonPrimary"
|
|
||||||
}, /* @__PURE__ */ import_react7.default.createElement("span", {
|
|
||||||
className: "ButtonInner-sc-14ud5tc-0 ButtonInner-small encore-bright-accent-set"
|
|
||||||
}, "Save"))));
|
|
||||||
};
|
|
||||||
var text_input_dialog_default = TextInputDialog;
|
|
||||||
|
|
||||||
// src/components/searchbar.tsx
|
|
||||||
var import_react8 = __toESM(require_react());
|
|
||||||
var SearchBar = (props) => {
|
|
||||||
const { setSearch, placeholder } = props;
|
|
||||||
const handleChange = (e) => {
|
|
||||||
setSearch(e.target.value);
|
|
||||||
};
|
|
||||||
return /* @__PURE__ */ import_react8.default.createElement("div", {
|
|
||||||
className: "x-filterBox-filterInputContainer x-filterBox-expandedOrHasFilter",
|
|
||||||
role: "search"
|
|
||||||
}, /* @__PURE__ */ import_react8.default.createElement("input", {
|
|
||||||
type: "text",
|
|
||||||
className: "x-filterBox-filterInput",
|
|
||||||
role: "searchbox",
|
|
||||||
maxLength: 80,
|
|
||||||
autoCorrect: "off",
|
|
||||||
autoCapitalize: "off",
|
|
||||||
spellCheck: "false",
|
|
||||||
placeholder: `Search ${placeholder}`,
|
|
||||||
"aria-hidden": "false",
|
|
||||||
onChange: handleChange
|
|
||||||
}), /* @__PURE__ */ import_react8.default.createElement("div", {
|
|
||||||
className: "x-filterBox-overlay"
|
|
||||||
}, /* @__PURE__ */ import_react8.default.createElement("span", {
|
|
||||||
className: "x-filterBox-searchIconContainer"
|
|
||||||
}, /* @__PURE__ */ import_react8.default.createElement("svg", {
|
|
||||||
"data-encore-id": "icon",
|
|
||||||
role: "img",
|
|
||||||
"aria-hidden": "true",
|
|
||||||
className: "Svg-sc-ytk21e-0 Svg-img-icon-small x-filterBox-searchIcon",
|
|
||||||
viewBox: "0 0 16 16"
|
|
||||||
}, /* @__PURE__ */ import_react8.default.createElement("path", {
|
|
||||||
d: "M7 1.75a5.25 5.25 0 1 0 0 10.5 5.25 5.25 0 0 0 0-10.5zM.25 7a6.75 6.75 0 1 1 12.096 4.12l3.184 3.185a.75.75 0 1 1-1.06 1.06L11.304 12.2A6.75 6.75 0 0 1 .25 7z"
|
|
||||||
})))), /* @__PURE__ */ import_react8.default.createElement("button", {
|
|
||||||
className: "x-filterBox-expandButton",
|
|
||||||
"aria-hidden": "false",
|
|
||||||
"aria-label": "Search Playlists"
|
|
||||||
}, /* @__PURE__ */ import_react8.default.createElement("svg", {
|
|
||||||
"data-encore-id": "icon",
|
|
||||||
role: "img",
|
|
||||||
"aria-hidden": "true",
|
|
||||||
className: "Svg-sc-ytk21e-0 Svg-img-icon-small x-filterBox-searchIcon",
|
|
||||||
viewBox: "0 0 16 16"
|
|
||||||
}, /* @__PURE__ */ import_react8.default.createElement("path", {
|
|
||||||
d: "M7 1.75a5.25 5.25 0 1 0 0 10.5 5.25 5.25 0 0 0 0-10.5zM.25 7a6.75 6.75 0 1 1 12.096 4.12l3.184 3.185a.75.75 0 1 1-1.06 1.06L11.304 12.2A6.75 6.75 0 0 1 .25 7z"
|
|
||||||
}))));
|
|
||||||
};
|
|
||||||
var searchbar_default = SearchBar;
|
|
||||||
|
|
||||||
// src/components/album_menu_item.tsx
|
|
||||||
var createCollection = () => {
|
|
||||||
const onSave = (value) => {
|
|
||||||
SpicetifyLibrary.CollectionWrapper.createCollection(value);
|
|
||||||
};
|
|
||||||
Spicetify.PopupModal.display({
|
|
||||||
title: "Create Collection",
|
|
||||||
content: /* @__PURE__ */ import_react9.default.createElement(text_input_dialog_default, {
|
|
||||||
def: "New Collection",
|
|
||||||
placeholder: "Collection Name",
|
|
||||||
onSave
|
|
||||||
})
|
|
||||||
});
|
|
||||||
};
|
|
||||||
var CollectionSearchMenu = () => {
|
|
||||||
const { MenuItem } = Spicetify.ReactComponent;
|
|
||||||
const { SVGIcons } = Spicetify;
|
|
||||||
const [textFilter, setTextFilter] = import_react9.default.useState("");
|
|
||||||
const [collections, setCollections] = import_react9.default.useState(null);
|
|
||||||
const context = import_react9.default.useContext(Spicetify.ContextMenuV2._context);
|
|
||||||
const uri = context?.props?.uri;
|
|
||||||
import_react9.default.useEffect(() => {
|
|
||||||
const fetchCollections = async () => {
|
|
||||||
const res = await SpicetifyLibrary.CollectionWrapper.getCollectionItems({ textFilter });
|
|
||||||
setCollections(res);
|
|
||||||
};
|
|
||||||
fetchCollections();
|
|
||||||
}, [textFilter]);
|
|
||||||
if (!collections)
|
|
||||||
return /* @__PURE__ */ import_react9.default.createElement(import_react9.default.Fragment, null);
|
|
||||||
const addToCollection = (collectionUri) => {
|
|
||||||
SpicetifyLibrary.CollectionWrapper.addAlbumToCollection(collectionUri, uri);
|
|
||||||
};
|
|
||||||
const activeCollections = SpicetifyLibrary.CollectionWrapper.getCollectionsWithAlbum(uri);
|
|
||||||
const hasCollections = activeCollections.length > 0;
|
|
||||||
const removeFromCollections = () => {
|
|
||||||
activeCollections.forEach((collection) => {
|
|
||||||
SpicetifyLibrary.CollectionWrapper.removeAlbumFromCollection(collection.uri, uri);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
const allCollectionsLength = collections.unfilteredLength;
|
|
||||||
const menuItems = collections.items.map((collection, index) => {
|
|
||||||
return /* @__PURE__ */ import_react9.default.createElement(MenuItem, {
|
|
||||||
key: collection.uri,
|
|
||||||
onClick: () => {
|
|
||||||
addToCollection(collection.uri);
|
|
||||||
},
|
|
||||||
divider: index === 0 ? "before" : void 0
|
|
||||||
}, collection.name);
|
|
||||||
});
|
|
||||||
const menuLength = allCollectionsLength + (hasCollections ? 1 : 0);
|
|
||||||
return /* @__PURE__ */ import_react9.default.createElement("div", {
|
|
||||||
className: "main-contextMenu-filterPlaylistSearchContainer",
|
|
||||||
style: { "--context-menu-submenu-length": `${menuLength}` }
|
|
||||||
}, /* @__PURE__ */ import_react9.default.createElement("li", {
|
|
||||||
role: "presentation",
|
|
||||||
className: "main-contextMenu-filterPlaylistSearch"
|
|
||||||
}, /* @__PURE__ */ import_react9.default.createElement("div", {
|
|
||||||
role: "menuitem"
|
|
||||||
}, /* @__PURE__ */ import_react9.default.createElement(searchbar_default, {
|
|
||||||
setSearch: setTextFilter,
|
|
||||||
placeholder: "collections"
|
|
||||||
}))), /* @__PURE__ */ import_react9.default.createElement(MenuItem, {
|
|
||||||
key: "new-collection",
|
|
||||||
leadingIcon: /* @__PURE__ */ import_react9.default.createElement(leading_icon_default, {
|
|
||||||
path: SVGIcons["plus2px"]
|
|
||||||
}),
|
|
||||||
onClick: createCollection
|
|
||||||
}, "Create collection"), hasCollections && /* @__PURE__ */ import_react9.default.createElement(MenuItem, {
|
|
||||||
key: "remove-collection",
|
|
||||||
leadingIcon: /* @__PURE__ */ import_react9.default.createElement(leading_icon_default, {
|
|
||||||
path: SVGIcons["minus"]
|
|
||||||
}),
|
|
||||||
onClick: removeFromCollections
|
|
||||||
}, "Remove from all"), menuItems);
|
|
||||||
};
|
|
||||||
var AlbumMenuItem = () => {
|
|
||||||
const { MenuSubMenuItem } = Spicetify.ReactComponent;
|
|
||||||
const { SVGIcons } = Spicetify;
|
|
||||||
return /* @__PURE__ */ import_react9.default.createElement(MenuSubMenuItem, {
|
|
||||||
displayText: "Add to collection",
|
|
||||||
divider: "after",
|
|
||||||
leadingIcon: /* @__PURE__ */ import_react9.default.createElement(leading_icon_default, {
|
|
||||||
path: SVGIcons["plus2px"]
|
|
||||||
})
|
|
||||||
}, /* @__PURE__ */ import_react9.default.createElement(CollectionSearchMenu, null));
|
|
||||||
};
|
|
||||||
var album_menu_item_default = AlbumMenuItem;
|
|
||||||
|
|
||||||
// src/extensions/folder_image_wrapper.ts
|
// src/extensions/folder_image_wrapper.ts
|
||||||
var FolderImageWrapper = class extends EventTarget {
|
var _FolderImageWrapper = class extends EventTarget {
|
||||||
_folderImages;
|
_folderImages;
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
@ -757,7 +825,9 @@ var library = (() => {
|
||||||
localStorage.setItem("library:folderImages", JSON.stringify(this._folderImages));
|
localStorage.setItem("library:folderImages", JSON.stringify(this._folderImages));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var folder_image_wrapper_default = FolderImageWrapper;
|
var FolderImageWrapper2 = _FolderImageWrapper;
|
||||||
|
__publicField(FolderImageWrapper2, "INSTANCE", new _FolderImageWrapper());
|
||||||
|
window.FolderImageWrapper = FolderImageWrapper2.INSTANCE;
|
||||||
|
|
||||||
// src/extensions/extension.tsx
|
// src/extensions/extension.tsx
|
||||||
var styleLink = document.createElement("link");
|
var styleLink = document.createElement("link");
|
||||||
|
@ -773,6 +843,7 @@ var library = (() => {
|
||||||
};
|
};
|
||||||
var FolderImage = ({ url }) => {
|
var FolderImage = ({ url }) => {
|
||||||
return /* @__PURE__ */ import_react10.default.createElement("img", {
|
return /* @__PURE__ */ import_react10.default.createElement("img", {
|
||||||
|
alt: "Folder Image",
|
||||||
"aria-hidden": "true",
|
"aria-hidden": "true",
|
||||||
draggable: "false",
|
draggable: "false",
|
||||||
loading: "eager",
|
loading: "eager",
|
||||||
|
@ -793,7 +864,7 @@ var library = (() => {
|
||||||
d: "M1 4a2 2 0 0 1 2-2h5.155a3 3 0 0 1 2.598 1.5l.866 1.5H21a2 2 0 0 1 2 2v13a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V4zm7.155 0H3v16h18V7H10.464L9.021 4.5a1 1 0 0 0-.866-.5z"
|
d: "M1 4a2 2 0 0 1 2-2h5.155a3 3 0 0 1 2.598 1.5l.866 1.5H21a2 2 0 0 1 2 2v13a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V4zm7.155 0H3v16h18V7H10.464L9.021 4.5a1 1 0 0 0-.866-.5z"
|
||||||
})));
|
})));
|
||||||
};
|
};
|
||||||
var SpicetifyLibrary2 = class {
|
var SpicetifyLibrary = class {
|
||||||
ConfigWrapper = new config_wrapper_default(
|
ConfigWrapper = new config_wrapper_default(
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
|
@ -812,16 +883,25 @@ var library = (() => {
|
||||||
type: "toggle",
|
type: "toggle",
|
||||||
def: false,
|
def: false,
|
||||||
callback: setSearchBarSize
|
callback: setSearchBarSize
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
name: "Playlists Page",
|
||||||
|
key: "show-playlists",
|
||||||
|
type: "toggle",
|
||||||
|
def: true,
|
||||||
|
sectionHeader: "Pages"
|
||||||
|
},
|
||||||
|
{ name: "Albums Page", key: "show-albums", type: "toggle", def: true },
|
||||||
|
{ name: "Collections Page", key: "show-collections", type: "toggle", def: true },
|
||||||
|
{ name: "Artists Page", key: "show-artists", type: "toggle", def: true },
|
||||||
|
{ name: "Shows Page", key: "show-shows", type: "toggle", def: true }
|
||||||
],
|
],
|
||||||
"library"
|
"library"
|
||||||
);
|
);
|
||||||
CollectionWrapper = new collections_wrapper_default();
|
|
||||||
FolderImageWrapper = new folder_image_wrapper_default();
|
|
||||||
};
|
};
|
||||||
window.SpicetifyLibrary = new SpicetifyLibrary2();
|
window.SpicetifyLibrary = new SpicetifyLibrary();
|
||||||
(function wait() {
|
(function wait() {
|
||||||
const { LocalStorageAPI } = Spicetify?.Platform;
|
const { LocalStorageAPI } = Spicetify.Platform;
|
||||||
if (!LocalStorageAPI) {
|
if (!LocalStorageAPI) {
|
||||||
setTimeout(wait, 100);
|
setTimeout(wait, 100);
|
||||||
return;
|
return;
|
||||||
|
@ -829,22 +909,23 @@ var library = (() => {
|
||||||
main(LocalStorageAPI);
|
main(LocalStorageAPI);
|
||||||
})();
|
})();
|
||||||
function main(LocalStorageAPI) {
|
function main(LocalStorageAPI) {
|
||||||
const isAlbum = (props) => {
|
const isAlbum = (props) => props.uri?.includes("album");
|
||||||
return props.uri?.includes("album");
|
const isArtist = (props) => props.uri?.includes("artist");
|
||||||
};
|
|
||||||
Spicetify.ContextMenuV2.registerItem(/* @__PURE__ */ import_react10.default.createElement(album_menu_item_default, null), isAlbum);
|
Spicetify.ContextMenuV2.registerItem(/* @__PURE__ */ import_react10.default.createElement(album_menu_item_default, null), isAlbum);
|
||||||
|
Spicetify.ContextMenuV2.registerItem(/* @__PURE__ */ import_react10.default.createElement(artist_menu_item_default, null), isArtist);
|
||||||
|
Spicetify.Platform.LibraryAPI.getEvents()._emitter.addListener("update", () => CollectionsWrapper.cleanCollections());
|
||||||
function injectFolderImages() {
|
function injectFolderImages() {
|
||||||
const rootlist = document.querySelector(".main-rootlist-wrapper > div:nth-child(2)");
|
const rootlist = document.querySelector(".main-rootlist-wrapper > div:nth-child(2)");
|
||||||
if (!rootlist)
|
if (!rootlist)
|
||||||
return setTimeout(injectFolderImages, 100);
|
return setTimeout(injectFolderImages, 100);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
Array.from(rootlist.children).forEach((el) => {
|
for (const el of Array.from(rootlist.children)) {
|
||||||
const uri = el.querySelector(".main-yourLibraryX-listItemGroup")?.getAttribute("aria-labelledby")?.slice(14);
|
const uri = el.querySelector("[aria-labelledby]")?.getAttribute("aria-labelledby")?.slice(14);
|
||||||
if (uri?.includes("folder")) {
|
if (uri?.includes("folder")) {
|
||||||
const imageBox = el.querySelector(".x-entityImage-imageContainer");
|
const imageBox = el.querySelector(".x-entityImage-imageContainer");
|
||||||
if (!imageBox)
|
if (!imageBox)
|
||||||
return;
|
return;
|
||||||
const imageUrl = window.SpicetifyLibrary.FolderImageWrapper.getFolderImage(uri);
|
const imageUrl = FolderImageWrapper.getFolderImage(uri);
|
||||||
if (!imageUrl)
|
if (!imageUrl)
|
||||||
import_react_dom.default.render(/* @__PURE__ */ import_react10.default.createElement(FolderPlaceholder, null), imageBox);
|
import_react_dom.default.render(/* @__PURE__ */ import_react10.default.createElement(FolderPlaceholder, null), imageBox);
|
||||||
else
|
else
|
||||||
|
@ -852,17 +933,13 @@ var library = (() => {
|
||||||
url: imageUrl
|
url: imageUrl
|
||||||
}), imageBox);
|
}), imageBox);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}, 500);
|
}, 500);
|
||||||
}
|
}
|
||||||
injectFolderImages();
|
injectFolderImages();
|
||||||
window.SpicetifyLibrary.FolderImageWrapper.addEventListener("update", () => {
|
FolderImageWrapper.addEventListener("update", injectFolderImages);
|
||||||
injectFolderImages();
|
|
||||||
});
|
|
||||||
function injectYLXButtons() {
|
function injectYLXButtons() {
|
||||||
const ylx_filter = document.querySelector(
|
const ylx_filter = document.querySelector(".main-yourLibraryX-libraryRootlist > .main-yourLibraryX-libraryFilter");
|
||||||
".main-yourLibraryX-libraryRootlist > .main-yourLibraryX-libraryFilter"
|
|
||||||
);
|
|
||||||
if (!ylx_filter) {
|
if (!ylx_filter) {
|
||||||
return setTimeout(injectYLXButtons, 100);
|
return setTimeout(injectYLXButtons, 100);
|
||||||
}
|
}
|
||||||
|
@ -887,37 +964,17 @@ var library = (() => {
|
||||||
collapseButton
|
collapseButton
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
function injectExpandButton() {
|
|
||||||
const sidebarHeader = document.querySelector("li.main-yourLibraryX-navItem[data-id='/library']");
|
|
||||||
if (!sidebarHeader) {
|
|
||||||
return setTimeout(injectExpandButton, 100);
|
|
||||||
}
|
|
||||||
const expandButton = document.createElement("span");
|
|
||||||
expandButton.classList.add("expand-button");
|
|
||||||
sidebarHeader.appendChild(expandButton);
|
|
||||||
import_react_dom.default.render(/* @__PURE__ */ import_react10.default.createElement(expand_button_default, null), expandButton);
|
|
||||||
}
|
|
||||||
function removeExpandButton() {
|
|
||||||
const expandButton = document.querySelector(".expand-button");
|
|
||||||
if (expandButton)
|
|
||||||
expandButton.remove();
|
|
||||||
}
|
|
||||||
const state = LocalStorageAPI.getItem("ylx-sidebar-state");
|
const state = LocalStorageAPI.getItem("ylx-sidebar-state");
|
||||||
if (state === 0) {
|
if (state === 0)
|
||||||
injectYLXButtons();
|
injectYLXButtons();
|
||||||
} else if (state === 1) {
|
|
||||||
injectExpandButton();
|
|
||||||
}
|
|
||||||
LocalStorageAPI.getEvents()._emitter.addListener("update", (e) => {
|
LocalStorageAPI.getEvents()._emitter.addListener("update", (e) => {
|
||||||
const { key, value } = e.data;
|
const { key, value } = e.data;
|
||||||
if (key === "ylx-sidebar-state" && value === 0) {
|
if (key === "ylx-sidebar-state" && value === 0) {
|
||||||
injectFolderImages();
|
injectFolderImages();
|
||||||
injectYLXButtons();
|
injectYLXButtons();
|
||||||
removeExpandButton();
|
|
||||||
}
|
}
|
||||||
if (key === "ylx-sidebar-state" && value === 1) {
|
if (key === "ylx-sidebar-state" && value === 1) {
|
||||||
injectFolderImages();
|
injectFolderImages();
|
||||||
injectExpandButton();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ var library = (() => {
|
||||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||||
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
||||||
var __export = (target, all) => {
|
var __export = (target, all) => {
|
||||||
for (var name in all)
|
for (var name in all)
|
||||||
__defProp(target, name, { get: all[name], enumerable: true });
|
__defProp(target, name, { get: all[name], enumerable: true });
|
||||||
|
@ -21,13 +22,17 @@ var library = (() => {
|
||||||
return to;
|
return to;
|
||||||
};
|
};
|
||||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||||
|
var __publicField = (obj, key, value) => {
|
||||||
|
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
|
||||||
// src/extensions/folder_image_wrapper.ts
|
// src/extensions/folder_image_wrapper.ts
|
||||||
var folder_image_wrapper_exports = {};
|
var folder_image_wrapper_exports = {};
|
||||||
__export(folder_image_wrapper_exports, {
|
__export(folder_image_wrapper_exports, {
|
||||||
default: () => folder_image_wrapper_default
|
default: () => folder_image_wrapper_default
|
||||||
});
|
});
|
||||||
var FolderImageWrapper = class extends EventTarget {
|
var _FolderImageWrapper = class extends EventTarget {
|
||||||
_folderImages;
|
_folderImages;
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
@ -54,6 +59,9 @@ var library = (() => {
|
||||||
localStorage.setItem("library:folderImages", JSON.stringify(this._folderImages));
|
localStorage.setItem("library:folderImages", JSON.stringify(this._folderImages));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
var FolderImageWrapper = _FolderImageWrapper;
|
||||||
|
__publicField(FolderImageWrapper, "INSTANCE", new _FolderImageWrapper());
|
||||||
|
window.FolderImageWrapper = FolderImageWrapper.INSTANCE;
|
||||||
var folder_image_wrapper_default = FolderImageWrapper;
|
var folder_image_wrapper_default = FolderImageWrapper;
|
||||||
return __toCommonJS(folder_image_wrapper_exports);
|
return __toCommonJS(folder_image_wrapper_exports);
|
||||||
})();
|
})();
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,4 +1,4 @@
|
||||||
/* ../../../AppData/Local/Temp/tmp-5152-1Ex7Bvh4Tu6u/18f3cb8bc8b4/navBar.module.css */
|
/* ../../../AppData/Local/Temp/tmp-4464-wbZ6O1BKhuot/19178f16f304/navBar.module.css */
|
||||||
.navBar-module__topBarHeaderItem___piw4C_library {
|
.navBar-module__topBarHeaderItem___piw4C_library {
|
||||||
-webkit-app-region: no-drag;
|
-webkit-app-region: no-drag;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
@ -46,7 +46,7 @@ div.navBar-module__topBarHeaderItemLink___xA4uv_library {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ../../../AppData/Local/Temp/tmp-5152-1Ex7Bvh4Tu6u/18f3cb8baff0/app.css */
|
/* ../../../AppData/Local/Temp/tmp-4464-wbZ6O1BKhuot/19178f16dc80/app.css */
|
||||||
:root {
|
:root {
|
||||||
--library-card-size: 180px;
|
--library-card-size: 180px;
|
||||||
--library-searchbar-size: 200px;
|
--library-searchbar-size: 200px;
|
||||||
|
@ -57,6 +57,10 @@ div.navBar-module__topBarHeaderItemLink___xA4uv_library {
|
||||||
#library-app .grid {
|
#library-app .grid {
|
||||||
grid-template-columns: repeat(auto-fill, minmax(var(--library-card-size), 1fr)) !important;
|
grid-template-columns: repeat(auto-fill, minmax(var(--library-card-size), 1fr)) !important;
|
||||||
}
|
}
|
||||||
|
#library-app .main-card-cardContainer {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
#library-app .load-more-card {
|
#library-app .load-more-card {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
|
@ -100,7 +104,7 @@ div.navBar-module__topBarHeaderItemLink___xA4uv_library {
|
||||||
align-self: end;
|
align-self: end;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ../../../AppData/Local/Temp/tmp-5152-1Ex7Bvh4Tu6u/18f3cb8bc361/external.css */
|
/* ../../../AppData/Local/Temp/tmp-4464-wbZ6O1BKhuot/19178f16ee21/external.css */
|
||||||
body:not(.show-ylx-filters) .main-yourLibraryX-filterArea:not(:has(> .main-yourLibraryX-libraryFilter)),
|
body:not(.show-ylx-filters) .main-yourLibraryX-filterArea:not(:has(> .main-yourLibraryX-libraryFilter)),
|
||||||
.main-yourLibraryX-header:not(:has(> .main-yourLibraryX-headerContent > .main-yourLibraryX-collapseButton > button:nth-child(2))),
|
.main-yourLibraryX-header:not(:has(> .main-yourLibraryX-headerContent > .main-yourLibraryX-collapseButton > button:nth-child(2))),
|
||||||
.main-yourLibraryX-collapseButton > button:first-child,
|
.main-yourLibraryX-collapseButton > button:first-child,
|
||||||
|
@ -113,10 +117,12 @@ body:not(.show-ylx-filters) .main-yourLibraryX-filterArea:not(:has(> .main-yourL
|
||||||
.main-yourLibraryX-header {
|
.main-yourLibraryX-header {
|
||||||
margin-top: -8px;
|
margin-top: -8px;
|
||||||
}
|
}
|
||||||
.main-yourLibraryX-librarySortWrapper button span:first-child {
|
.main-yourLibraryX-libraryFilter .main-yourLibraryX-librarySortWrapper button span:first-child,
|
||||||
|
.main-yourLibraryX-libraryFilter span[role=presentation] span[role=presentation] button span:first-child {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
.main-yourLibraryX-librarySortWrapper {
|
.main-yourLibraryX-libraryFilter .main-yourLibraryX-librarySortWrapper,
|
||||||
|
.main-yourLibraryX-libraryFilter span[role=presentation] {
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
}
|
}
|
||||||
.toggle-filters-button > button:after,
|
.toggle-filters-button > button:after,
|
||||||
|
@ -140,21 +146,24 @@ li.main-yourLibraryX-navItem[data-id="/library"] {
|
||||||
li.main-yourLibraryX-navItem[data-id="/library"] > a {
|
li.main-yourLibraryX-navItem[data-id="/library"] > a {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
.toggle-filters-button > button,
|
.main-yourLibraryX-libraryFilter .toggle-filters-button > button,
|
||||||
.collapse-button > button,
|
.main-yourLibraryX-libraryFilter .collapse-button > button,
|
||||||
.main-yourLibraryX-librarySortWrapper > button {
|
.main-yourLibraryX-libraryFilter .main-yourLibraryX-librarySortWrapper > button,
|
||||||
|
.main-yourLibraryX-libraryFilter span[role=presentation] span[role=presentation] > button {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
.toggle-filters-button,
|
.main-yourLibraryX-libraryFilter .toggle-filters-button,
|
||||||
.collapse-button,
|
.main-yourLibraryX-libraryFilter .collapse-button,
|
||||||
.main-yourLibraryX-librarySortWrapper {
|
.main-yourLibraryX-libraryFilter .main-yourLibraryX-librarySortWrapper,
|
||||||
|
.main-yourLibraryX-libraryFilter span[role=presentation] span[role=presentation] {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-basis: 32px;
|
flex-basis: 32px;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
min-width: 24px;
|
min-width: 24px;
|
||||||
flex-shrink: 10;
|
flex-shrink: 10;
|
||||||
}
|
}
|
||||||
.main-yourLibraryX-librarySortWrapper > button > span:nth-child(2) {
|
.main-yourLibraryX-libraryFilter .main-yourLibraryX-librarySortWrapper > button > span:nth-child(2),
|
||||||
|
.main-yourLibraryX-libraryFilter span[role=presentation] span[role=presentation] > button > span:nth-child(2) {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
.LayoutResizer__resize-bar {
|
.LayoutResizer__resize-bar {
|
||||||
|
@ -227,7 +236,7 @@ li.main-yourLibraryX-navItem[data-id="/library"] > a {
|
||||||
transform: scale(1.04);
|
transform: scale(1.04);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ../../../AppData/Local/Temp/tmp-5152-1Ex7Bvh4Tu6u/18f3cb8bc5f2/config_modal.css */
|
/* ../../../AppData/Local/Temp/tmp-4464-wbZ6O1BKhuot/19178f16f0a2/config_modal.css */
|
||||||
.config-container {
|
.config-container {
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -304,7 +313,7 @@ li.main-yourLibraryX-navItem[data-id="/library"] > a {
|
||||||
width: 200px;
|
width: 200px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ../../../AppData/Local/Temp/tmp-5152-1Ex7Bvh4Tu6u/18f3cb8bc713/shared.css */
|
/* ../../../AppData/Local/Temp/tmp-4464-wbZ6O1BKhuot/19178f16f163/shared.css */
|
||||||
.grid {
|
.grid {
|
||||||
--grid-gap: 24px;
|
--grid-gap: 24px;
|
||||||
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)) !important;
|
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)) !important;
|
||||||
|
@ -327,6 +336,20 @@ li.main-yourLibraryX-navItem[data-id="/library"] > a {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 24px;
|
gap: 24px;
|
||||||
}
|
}
|
||||||
|
.badge {
|
||||||
|
position: absolute;
|
||||||
|
top: 3%;
|
||||||
|
left: 3%;
|
||||||
|
height: 30px;
|
||||||
|
width: 30px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: rgb(65, 110, 170);
|
||||||
|
color: white;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
.page-header {
|
.page-header {
|
||||||
align-content: space-between;
|
align-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
|
@ -29,4 +29,4 @@ custom_apps = library|lyrics-plus|marketplace|stats
|
||||||
; DO NOT CHANGE!
|
; DO NOT CHANGE!
|
||||||
[Backup]
|
[Backup]
|
||||||
version = 1.2.42.290.g242057a2
|
version = 1.2.42.290.g242057a2
|
||||||
with = 2.37.1
|
with = 2.38.3
|
||||||
|
|
Loading…
Add table
Reference in a new issue