Update 2024-08-27

This commit is contained in:
Kristofers Solo 2024-08-27 10:39:38 +03:00
parent a2bd1bc111
commit d888080cc7
894 changed files with 541718 additions and 81 deletions

View File

@ -479,11 +479,11 @@ local globalkeys = gears.table.join(
-- awful.key({ modkey, "Control" }, "q", awesome.quit, { description = "quit awesome", group = "awesome" }),
awful.key({ modkey }, "b", function()
awful.spawn("librewolf")
end, { description = "open librewolf", group = "launcher" }),
awful.spawn("floorp")
end, { description = "open browser", group = "launcher" }),
awful.key({ modkey }, "n", function()
awful.spawn("spacefm")
end, { description = "open spacefm", group = "launcher" }),
awful.spawn("alacritty -e yazi")
end, { description = "open yazi", group = "launcher" }),
awful.key({ modkey }, "l", function()
awful.tag.incmwfact(0.05)

View File

@ -196,7 +196,7 @@ net_download = 100
net_upload = 100
#* Use network graphs auto rescaling mode, ignores any values set above and rescales down to 10 Kibibytes at the lowest.
net_auto = False
net_auto = True
#* Sync the auto scaling for download and upload to whichever currently has the highest scale.
net_sync = False

View File

@ -123,7 +123,7 @@
### Text ###
font = JetBrainsMono NF 14
font = JetBrainsMono NF 8
icon_theme = "rose-pine-icons"
enable_recursive_icon_lookup = true

View File

@ -26,7 +26,23 @@
# List available modules with "fastfetch --list-modules".
# Get the default structure with "fastfetch --print-structure".
# --structure Title:Separator:OS:Host:Kernel:Uptime:Packages:Shell:Resolution:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Terminal:TerminalFont:CPU:GPU:Memory:Disk:Battery:Locale:Break:Colors
--structure Title:Separator:OS:Host:Kernel:Uptime:Break:Packages:Break:Memory:Disk:Battery:Break:DateTime:Break:Colors
--structure
Title
Separator
OS
Host
Kernel
Uptime
Break
Packages
Break
Memory
Disk
Battery
Break
DateTime
Break
Colors
# Multithreading option:
# Sets if fastfetch should use multiple threads to detect the values.

View File

@ -0,0 +1,19 @@
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"modules": [
"title",
"separator",
"os",
"host",
"kernel",
"uptime",
"break",
"packages",
"break",
"memory",
"disk",
"battery",
"break",
"colors"
]
}

View File

@ -47,7 +47,10 @@ alias \
sv="rsv" \
v="$EDITOR" \
weather="curl wttr.in/" \
wg-down="wg-quick down wg0" \
wg-up="wg-quick up wg0" \
ww="$EDITOR ~/neorg/" \
yarn="yarn --use-yarnrc $XDG_CONFIG_HOME/yarn/config" \
yy="yazi"
# doas not required for some system commands

View File

@ -9,16 +9,17 @@ typeset -U PATH path
# Adds `~/.local/bin` to $PATH
export PATH="$PATH:${$(find ~/.local/bin -type d -printf %p:)%%:}"
export PATH="$PATH:~/.spicetify"
# Disable files
export LESSHISTFILE=-
# export $(dbus-launch)
export $(dbus-launch)
unsetopt PROMPT_SP
# Default Apps
export BROWSER="librewolf"
export BROWSER="floorp"
export EDITOR="nvim"
export IMAGE="nsxiv"
export READER="zathura"
@ -32,58 +33,59 @@ export WM="awesome"
export XDG_CACHE_HOME="$HOME/.cache"
export XDG_CONFIG_HOME="$HOME/.config"
export XDG_DATA_HOME="$HOME/.local/share"
export XDG_STATE_HOME="$HOME/.local/share"
export XDG_RUNTIME_DIR="$HOME/.cache/xdgr"
export XDG_STATE_HOME="$HOME/.local/share"
export HYPRSHOT_DIR="$HOME/Pictures/screenshots"
export NODE_REPL_HISTORY="$XDG_DATA_HOME/node_repl_history"
export DOCKER_CONFIG="$XDG_CONFIG_HOME/docker"
export ANDROID_HOME="$XDG_CONFIG_HOME/android"
export ANDROID_SDK_HOME="$XDG_CONFIG_HOME/android"
export ANDROID_USER_HOME="$XDG_DATA_HOME/android"
export ANDROID_HOME="$XDG_CONFIG_HOME/android"
export ANSIBLE_CONFIG="$XDG_CONFIG_HOME/ansible/ansible.cfg"
export CARGO_HOME="$XDG_DATA_HOME/cargo"
export CUDA_CACHE_PATH="$XDG_CACHE_HOME/nv"
export DOCKER_CONFIG="$XDG_CONFIG_HOME/docker"
export ELECTRUMDIR="$XDG_DATA_HOME/electrum"
export GNUPGHOME="$XDG_DATA_HOME/gnupg"
export GRADLE_USER_HOME="$XDG_DATA_HOME/gradle"
export XCURSOR_PATH="/usr/share/icons:$XDG_DATA_HOME/icons"
export IPYTHONDIR="$XDG_CONFIG_HOME/ipython"
export GOPATH="$XDG_DATA_HOME/go"
export GRADLE_USER_HOME="$XDG_DATA_HOME/gradle"
export GTK2_RC_FILES="$XDG_CONFIG_HOME/gtk-2.0/gtkrc"
export HISTFILE="$XDG_CONFIG_HOME/zsh/history"
export HISTFILE="$XDG_DATA_HOME/history"
export HISTFILE="$XDG_STATE_HOME/bash/history"
export INPUTRC="$XDG_CONFIG_HOME/shell/inputrc"
export IPYTHONDIR="$XDG_CONFIG_HOME/ipython"
export KERAS_HOME="$XDG_DATA_HOME/keras"
export KODI_DATA="$XDG_DATA_HOME/kodi"
export MBSYNCRC="$XDG_CONFIG_HOME/mbsync/config"
export MYPY_CACHE_DIR="$XDG_CACHE_HOME/mypy"
export MYSQL_HISTFILE="$XDG_DATA_HOME/mysql_history"
export NODE_REPL_HISTORY="$XDG_DATA_HOME/node_repl_history"
export NOTMUCH_CONFIG="$XDG_CONFIG_HOME/notmuch-config"
export NPM_CONFIG_USERCONFIG="$XDG_CACHE_HOME/npm/npmrc"
export PARALLEL_HOME="$XDG_CONFIG_HOME/parallel"
export PASSWORD_STORE_DIR="$XDG_DATA_HOME/password-store"
export PYENV_ROOT="$XDG_DATA_HOME/pyenv"
export PYTHONSTARTUP="$XDG_CONFIG_HOME/python/pythonrc"
export PYTHONSTARTUP="$HOME/python/pythonrc"
export REDISCLI_HISTFILE="$XDG_DATA_HOME/redis/rediscli_history"
export RUSTUP_HOME="$XDG_DATA_HOME/rustup"
export RYE_HOME="$XDG_DATA_HOME/rye"
export SSB_HOME="$XDG_DATA_HOME/zoom"
export STARSHIP_CONFIG="$XDG_CONFIG_HOME/starship/starship.toml"
export TEXMFVAR="$XDG_CACHE_HOME/texlive/texmf-var"
export TMUX_TMPDIR="$XDG_RUNTIME_DIR"
export UNISON="$XDG_DATA_HOME/unison"
export W3M_DIR="$XDG_DATA_HOME/w3m"
export WEECHAT_HOME="$XDG_CONFIG_HOME/weechat"
export WGETRC="$XDG_CONFIG_HOME/wget/wgetrc"
export WINEPREFIX="$XDG_DATA_HOME/wineprefixes/default"
export XAUTHORITY="$XDG_RUNTIME_DIR/Xauthority"
export XCURSOR_PATH="/usr/share/icons:$XDG_DATA_HOME/icons"
export XINITRC="$XDG_CONFIG_HOME/x11/xinitrc"
export ZDOTDIR="$XDG_CONFIG_HOME/zsh"
export _JAVA_OPTIONS=-Djava.util.prefs.userRoot="$XDG_CONFIG_HOME/java"
export _JAVA_OPTIONS="-Djava.util.prefs.userRoot=${XDG_CONFIG_HOME}/java - Djavafx.cachedir=${XDG_CACHE_HOME}/openjfx"
export PARALLEL_HOME="$XDG_CONFIG_HOME/parallel"
export MYSQL_HISTFILE="$XDG_DATA_HOME/mysql_history"
export HISTFILE="$XDG_STATE_HOME/bash/history"
export W3M_DIR="$XDG_DATA_HOME/w3m"
export RYE_HOME="$XDG_DATA_HOME/rye"
export _JAVA_OPTIONS=-Djava.util.prefs.userRoot="$XDG_CONFIG_HOME/java"
# Other program settings
export AWT_TOOLKIT="MToolkit wmname LG3D" # May have to install wmname

Binary file not shown.

BIN
.config/spicetify/Backup/xpui.spa Executable file

Binary file not shown.

View File

@ -0,0 +1,99 @@
# The Eternal Jukebox
For when your favorite song just isn't long enough.
![preview](https://raw.githubusercontent.com/Pithaya/spicetify-apps/main/custom-apps/eternal-jukebox/preview.png)
A rewrite of the [Infinite / Eternal Jukebox](https://eternalbox.dev/jukebox_index.html) for Spicetify.
It finds pathways through similar segments of the song and plays a never-ending and ever changing version of the song.
> **Warning**
> The custom app is still in **beta**.
> See [known issues](#known-issues) and [upcoming features](#upcoming-features).
## Auto Installation (Linux)
```
sh <(curl -s https://raw.githubusercontent.com/Pithaya/spicetify-apps/main/custom-apps/eternal-jukebox/src/install.sh)
```
## Manual Installation
1. Run `spicetify config-dir` to open the spicetify folder.
2. Go to the `CustomApps` folder.
3. Create a `eternal-jukebox` folder.
4. Download the custom app files as a zip from [here](https://github.com/Pithaya/spicetify-apps-dist/archive/refs/heads/dist/eternal-jukebox.zip).
5. Extract the zip and put the files inside the folder you created in step 3.
Then, run the following commands:
```sh
spicetify config custom_apps eternal-jukebox
spicetify apply
```
## Usage
A new "infinity" button allows you to enable and disable the jukebox. As long as the jukebox is enabled, the current song will play endlessly.
![button](https://raw.githubusercontent.com/Pithaya/spicetify-apps/main/custom-apps/eternal-jukebox/docs/button.JPG)
Changing the current song will automatically play it through the jukebox.
![sidebar](https://raw.githubusercontent.com/Pithaya/spicetify-apps/main/custom-apps/eternal-jukebox/docs/sidebar.JPG)
The custom app allows you to see a visualization of the jukebox's progress through the song.
![visualization](https://raw.githubusercontent.com/Pithaya/spicetify-apps/main/custom-apps/eternal-jukebox/docs/visualization.png)
The circle is made out of the different beats of the song. Branches, or edges are the path linking similar beats together.
Holding the `SHIFT` key allows you to keep repeating a part of the song by "jumping" through edges linking the same beats.
Clicking on a beat will seek to that part of the song.
Below the graph you will find some stats about the current song:
- **Total beats**: How many beats were played.
- **Current branch change**: The current percentage of chance to follow an edge when playing a beat.
- **Listen time**: How long you've been listening to the song.
### Settings
The settings button on the top right allows you to tune the jukebox.
![settings](https://raw.githubusercontent.com/Pithaya/spicetify-apps/main/custom-apps/eternal-jukebox/docs/settings.png)
- **Branch similarity threshold**: The maximum allowed "distance" between two branches. The higher it is, the more branches will be generated.
- **Branch probability range**: The minimum and maximum percentage of chance to use a branch each beat. The chance will start at the minimum value, and will increase by the **Branch probability ramp-up speed** value for every beat where it is not branching, until it reaches the maximum value.
- **Branch probability ramp-up speed**: How fast the **Branch probability chance** value should increase.
- **Loop extension optimization**: If checked, will try to add the longest backward branch it can at the last branching beat.
- **Allow only reverse branches**: If checked, will only add branches going back in the song.
- **Allow only long branches**: If checked, will only add long branches. A branch is considered long if it covers at least a fifth of the song's length.
- **Remove sequential branches**: If checked, will remove consecutive branches of the same length.
The reset button can be used to reset the settings to the default values.
## Known issues
- Audio lag when jumping between parts of the song
- Jukebox "freezing" and getting out of sync
- Songs getting stuck in short loops due to issues with the graph generation
## Upcoming features
- More graph interactivity
## Uninstall
1. Run `spicetify config-dir` to open the spicetify folder
2. Go to the `CustomApps` folder
3. Delete the `eternal-jukebox` folder
Then, run the following commands:
```sh
spicetify config custom_apps eternal-jukebox-
spicetify apply
```

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,9 @@
{
"name": "Eternal Jukebox",
"icon": "<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n style=\"stroke-width: 2px !important;\"\n>\n <path d=\"M18.178 8c5.096 0 5.096 8 0 8-5.095 0-7.133-8-12.739-8-4.585 0-4.585 8 0 8 5.606 0 7.644-8 12.74-8z\"></path>\n</svg>",
"active-icon": "<svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n style=\"stroke-width: 2px !important;\"\n>\n <path d=\"M18.178 8c5.096 0 5.096 8 0 8-5.095 0-7.133-8-12.739-8-4.585 0-4.585 8 0 8 5.606 0 7.644-8 12.74-8z\"></path>\n</svg>",
"subfiles": [],
"subfiles_extension": [
"extension.js"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 KiB

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
dist/* linguist-vendored

View File

@ -0,0 +1,147 @@
# Created by https://www.toptal.com/developers/gitignore/api/node
# Edit at https://www.toptal.com/developers/gitignore?templates=node
### Node ###
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# build-local directory
dist/
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional stylelint cache
.stylelintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
out
# Nuxt.js build / generate output
.nuxt
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# vuepress v2.x temp and cache directory
.temp
# Docusaurus cache and generated files
.docusaurus
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*
### Node Patch ###
# Serverless Webpack directories
.webpack/
# Optional stylelint cache
# SvelteKit build / generate output
.svelte-kit
# End of https://www.toptal.com/developers/gitignore/api/node

View File

@ -0,0 +1,27 @@
# History in Sidebar
Adds a shortcut for the "Recently Played" screen to the sidebar.
Saves one full click!
> If you like it, please consider starring it on GitHub 🌟
<p align="center">
<img src="https://github.com/Bergbok/Spicetify-Creations/assets/66174189/ded310d5-374a-4238-98b1-bd2fad737604"/></img>
</p>
## Installation
1. Install Spicetify ([guide](https://spicetify.app/docs/advanced-usage/installation))
2. Download it from [here](https://github.com/Bergbok/Spicetify-Creations/archive/refs/heads/dist/history-in-sidebar.zip)
3. Run `spicetify config-dir` in a terminal
4. Extract the zip into the CustomApps folder
5. Rename the extracted folder to `history-in-sidebar`
6. Run `spicetify config custom_apps history-in-sidebar`
7. Run `spicetify apply`
> If you get stuck check out [Spicetify's official guide](https://spicetify.app/docs/advanced-usage/custom-apps/).
## License
This repository is licensed under the [MIT License](https://github.com/Bergbok/Spicetify-Creations/blob/main/LICENSE).

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,17 @@
{
"name": "history-in-sidebar",
"version": "1.0.0",
"private": true,
"scripts": {
"build": "spicetify-creator",
"build-local": "spicetify-creator --out=dist --minify",
"watch": "spicetify-creator --watch"
},
"license": "MIT",
"devDependencies": {
"@types/node": "^20.11.24",
"@types/react": "^18.2.63",
"@types/react-dom": "^18.2.19",
"spicetify-creator": "^1.0.17"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

View File

@ -0,0 +1,13 @@
import React from 'react'
class App extends React.Component {
componentDidMount() {
Spicetify.Platform.History.push('/history');
}
render() {
return null;
}
}
export default App;

View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" viewBox="0 0 24 24" id="history">
<path d="M21.001 12a9 9 0 0 0-9-9 1 1 0 1 1 0-2c6.075 0 11 4.925 11 11s-4.925 11-11 11-11-4.925-11-11a1 1 0 1 1 2 0 9 9 0 1 0 18 0zM7.58 4.422a1.25 1.25 0 1 1-1.25-2.165 1.25 1.25 0 0 1 1.25 2.165z"></path>
<path d="M11.034 6a1 1 0 0 1 2 0v5H16a1 1 0 1 1 0 2h-4.966V6zM2.67 8.083a1.25 1.25 0 1 0 1.25-2.165 1.25 1.25 0 0 0-1.25 2.165z"></path>
</svg>

After

Width:  |  Height:  |  Size: 458 B

View File

@ -0,0 +1,6 @@
{
"displayName": "History",
"nameId": "history-in-sidebar",
"icon": "assets/icon.svg",
"activeIcon": "assets/icon.svg"
}

View File

@ -0,0 +1,14 @@
{
"compilerOptions": {
"target": "ES2017",
"jsx": "react",
"module": "commonjs",
"resolveJsonModule": true,
"outDir": "dist",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true
},
"include": ["./src/**/*", "../../libs/shared/src/types/**/*"]
}

View File

@ -0,0 +1,156 @@
(async function() {
while (!Spicetify.React || !Spicetify.ReactDOM) {
await new Promise(resolve => setTimeout(resolve, 10));
}
"use strict";
var library = (() => {
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/extensions/collection_wrapper.tsx
var collection_wrapper_exports = {};
__export(collection_wrapper_exports, {
default: () => collection_wrapper_default
});
// node_modules/uuid/dist/esm-browser/rng.js
var getRandomValues;
var rnds8 = new Uint8Array(16);
function rng() {
if (!getRandomValues) {
getRandomValues = typeof crypto !== "undefined" && crypto.getRandomValues && crypto.getRandomValues.bind(crypto);
if (!getRandomValues) {
throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");
}
}
return getRandomValues(rnds8);
}
// node_modules/uuid/dist/esm-browser/stringify.js
var byteToHex = [];
for (let i = 0; i < 256; ++i) {
byteToHex.push((i + 256).toString(16).slice(1));
}
function unsafeStringify(arr, offset = 0) {
return byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]];
}
// node_modules/uuid/dist/esm-browser/native.js
var randomUUID = typeof crypto !== "undefined" && crypto.randomUUID && crypto.randomUUID.bind(crypto);
var native_default = {
randomUUID
};
// node_modules/uuid/dist/esm-browser/v4.js
function v4(options, buf, offset) {
if (native_default.randomUUID && !buf && !options) {
return native_default.randomUUID();
}
options = options || {};
const rnds = options.random || (options.rng || rng)();
rnds[6] = rnds[6] & 15 | 64;
rnds[8] = rnds[8] & 63 | 128;
if (buf) {
offset = offset || 0;
for (let i = 0; i < 16; ++i) {
buf[offset + i] = rnds[i];
}
return buf;
}
return unsafeStringify(rnds);
}
var v4_default = v4;
// src/extensions/collection_wrapper.tsx
var CollectionWrapper = class {
constructor() {
this.getCollections = () => {
return this._collections;
};
this.createCollection = (name) => {
const collection = {
id: v4_default(),
name,
items: []
};
this._collections.push(collection);
this.saveCollections();
Spicetify.showNotification("Collection Created");
return collection;
};
this.deleteCollection = (collectionID) => {
this._collections = this._collections.filter((collection) => collection.id !== collectionID);
this.saveCollections();
Spicetify.showNotification("Collection Deleted");
};
this.getCollection = (collectionID) => {
return this._collections.find((collection) => collection.id === collectionID);
};
this.renameCollection = (collectionID, name) => {
const collection = this.getCollection(collectionID);
if (!collection)
throw new Error("Collection is not defined");
collection.name = name;
this.saveCollections();
Spicetify.showNotification("Collection Renamed");
};
this.addToCollection = (collectionID, albumURI) => {
const collection = this.getCollection(collectionID);
if (!collection)
throw new Error("Collection is not defined");
Spicetify.GraphQL.Request(Spicetify.GraphQL.Definitions.getAlbum, {
uri: albumURI,
locale: "en",
offset: 0,
limit: 1
}).then((res) => {
var _a, _b, _c, _d, _e, _f, _g;
const data = res.data.albumUnion;
const albumItem = {
uri: data.uri,
name: data.name,
artist: (_d = (_c = (_b = (_a = data.artists) == null ? void 0 : _a.items) == null ? void 0 : _b[0]) == null ? void 0 : _c.profile) == null ? void 0 : _d.name,
image: ((_g = (_f = (_e = data.coverArt) == null ? void 0 : _e.sources) == null ? void 0 : _f[0]) == null ? void 0 : _g.url) || ""
};
collection.items.push(albumItem);
this.saveCollections();
});
Spicetify.showNotification("Item Added to Collection");
};
this.removeFromCollection = (collectionID, albumURI) => {
const collection = this.getCollection(collectionID);
if (!collection)
throw new Error("Collection is not defined");
collection.items = collection.items.filter((album) => album.uri !== albumURI);
this.saveCollections();
Spicetify.showNotification("Item Removed from Collection");
};
this.getCollectionForItem = (albumURI) => {
return this._collections.filter((collection) => collection.items.some((item) => item.uri === albumURI));
};
this.saveCollections = () => {
localStorage.setItem("library:collections", JSON.stringify(this._collections));
};
this._collections = JSON.parse(localStorage.getItem("library:collections") || "[]");
}
};
var collection_wrapper_default = CollectionWrapper;
return __toCommonJS(collection_wrapper_exports);
})();
})();

View File

@ -0,0 +1,300 @@
(async function() {
while (!Spicetify.React || !Spicetify.ReactDOM) {
await new Promise(resolve => setTimeout(resolve, 10));
}
"use strict";
var library = (() => {
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
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) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
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
var collections_wrapper_exports = {};
__export(collections_wrapper_exports, {
default: () => collections_wrapper_default
});
// ../node_modules/uuid/dist/esm-browser/rng.js
var getRandomValues;
var rnds8 = new Uint8Array(16);
function rng() {
if (!getRandomValues) {
getRandomValues = typeof crypto !== "undefined" && crypto.getRandomValues && crypto.getRandomValues.bind(crypto);
if (!getRandomValues) {
throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");
}
}
return getRandomValues(rnds8);
}
// ../node_modules/uuid/dist/esm-browser/stringify.js
var byteToHex = [];
for (let i = 0; i < 256; ++i) {
byteToHex.push((i + 256).toString(16).slice(1));
}
function unsafeStringify(arr, offset = 0) {
return byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]];
}
// ../node_modules/uuid/dist/esm-browser/native.js
var randomUUID = typeof crypto !== "undefined" && crypto.randomUUID && crypto.randomUUID.bind(crypto);
var native_default = {
randomUUID
};
// ../node_modules/uuid/dist/esm-browser/v4.js
function v4(options, buf, offset) {
if (native_default.randomUUID && !buf && !options) {
return native_default.randomUUID();
}
options = options || {};
const rnds = options.random || (options.rng || rng)();
rnds[6] = rnds[6] & 15 | 64;
rnds[8] = rnds[8] & 63 | 128;
if (buf) {
offset = offset || 0;
for (let i = 0; i < 16; ++i) {
buf[offset + i] = rnds[i];
}
return buf;
}
return unsafeStringify(rnds);
}
var v4_default = v4;
// src/extensions/collections_wrapper.ts
var _CollectionsWrapper = class extends EventTarget {
_collections;
constructor() {
super();
this._collections = JSON.parse(localStorage.getItem("library:collections") || "[]");
}
saveCollections() {
localStorage.setItem("library:collections", JSON.stringify(this._collections));
this.dispatchEvent(new CustomEvent("update", { detail: this._collections }));
}
getCollection(uri) {
return this._collections.find((collection) => collection.uri === uri);
}
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({
filters: ["0"],
offset: 0,
limit: 9999
});
items.push(...albums.items.filter((album) => collection.items.includes(album.uri)));
return items;
}
async getContents(props) {
const { collectionUri, offset, limit, textFilter } = props;
let items = collectionUri ? await this.getCollectionContents(collectionUri) : this._collections;
const openedCollectionName = collectionUri ? this.getCollection(collectionUri)?.name : void 0;
if (textFilter) {
const regex = new RegExp(`\\b${textFilter}`, "i");
items = items.filter((collection) => regex.test(collection.name));
}
items = items.slice(offset, offset + limit);
return { items, totalLength: this._collections.length, offset, openedCollectionName };
}
async cleanCollections() {
for (const collection of this._collections) {
const boolArray = await Spicetify.Platform.LibraryAPI.contains(...collection.items);
if (boolArray.includes(false)) {
collection.items = collection.items.filter((_, i) => boolArray[i]);
this.saveCollections();
Spicetify.showNotification("Album removed from collection");
this.syncCollection(collection.uri);
}
}
}
async syncCollection(uri) {
const collection = this.getCollection(uri);
if (!collection)
return;
const { PlaylistAPI } = Spicetify.Platform;
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 = "") {
const id = v4_default();
this._collections.push({
type: "collection",
uri: id,
name,
items: [],
addedAt: new Date(),
lastPlayedAt: new Date(),
parentCollection
});
this.saveCollections();
Spicetify.showNotification("Collection created");
return id;
}
deleteCollection(uri) {
this._collections = this._collections.filter((collection) => collection.uri !== uri);
this.saveCollections();
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) {
const collection = this.getCollection(collectionUri);
if (!collection)
return;
await Spicetify.Platform.LibraryAPI.add({ uris: [albumUri] });
collection.items.push(albumUri);
this.saveCollections();
Spicetify.showNotification("Album added to collection");
this.syncCollection(collectionUri);
}
removeAlbumFromCollection(collectionUri, albumUri) {
const collection = this.getCollection(collectionUri);
if (!collection)
return;
collection.items = collection.items.filter((item) => item !== albumUri);
this.saveCollections();
Spicetify.showNotification("Album removed from collection");
this.syncCollection(collectionUri);
}
getCollectionsWithAlbum(albumUri) {
return this._collections.filter((collection) => {
return collection.items.some((item) => item === albumUri);
});
}
renameCollection(uri, name) {
const collection = this.getCollection(uri);
if (!collection)
return;
collection.name = name;
this.saveCollections();
Spicetify.showNotification("Collection renamed");
}
setCollectionImage(uri, url) {
const collection = this.getCollection(uri);
if (!collection)
return;
collection.image = url;
this.saveCollections();
Spicetify.showNotification("Collection image set");
}
removeCollectionImage(uri) {
const collection = this.getCollection(uri);
if (!collection)
return;
collection.image = void 0;
this.saveCollections();
Spicetify.showNotification("Collection image removed");
}
};
var CollectionsWrapper = _CollectionsWrapper;
__publicField(CollectionsWrapper, "INSTANCE", new _CollectionsWrapper());
window.CollectionsWrapper = CollectionsWrapper.INSTANCE;
var collections_wrapper_default = CollectionsWrapper;
return __toCommonJS(collections_wrapper_exports);
})();
})();

View File

@ -0,0 +1,280 @@
(async function() {
while (!Spicetify.React || !Spicetify.ReactDOM) {
await new Promise(resolve => setTimeout(resolve, 10));
}
"use strict";
var library = (() => {
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// external-global-plugin:react
var require_react = __commonJS({
"external-global-plugin:react"(exports, module) {
module.exports = Spicetify.React;
}
});
// src/extensions/config_loader.tsx
var config_loader_exports = {};
__export(config_loader_exports, {
default: () => config_loader_default
});
// src/components/settings_modal.tsx
var import_react = __toESM(require_react());
var TextInput = (props) => {
const textId = `text-input:${props.storageKey}`;
return /* @__PURE__ */ import_react.default.createElement("label", {
className: "text-input-wrapper"
}, /* @__PURE__ */ import_react.default.createElement("input", {
className: "text-input",
type: "text",
value: props.value || "",
"data-storage-key": props.storageKey,
placeholder: props.placeholder,
id: textId,
title: `Text input for ${props.storageKey}`,
onChange: props.onChange
}));
};
var Dropdown = (props) => {
const dropdownId = `dropdown:${props.storageKey}`;
return /* @__PURE__ */ import_react.default.createElement("label", {
className: "dropdown-wrapper"
}, /* @__PURE__ */ import_react.default.createElement("select", {
className: "dropdown-input",
value: props.value,
"data-storage-key": props.storageKey,
id: dropdownId,
title: `Dropdown for ${props.storageKey}`,
onChange: props.onChange
}, props.options.map((option, index) => /* @__PURE__ */ import_react.default.createElement("option", {
key: index,
value: option
}, option))));
};
var TooltipIcon = () => {
return /* @__PURE__ */ import_react.default.createElement("svg", {
role: "img",
height: "16",
width: "16",
className: "Svg-sc-ytk21e-0 uPxdw nW1RKQOkzcJcX6aDCZB4",
viewBox: "0 0 16 16"
}, /* @__PURE__ */ import_react.default.createElement("path", {
d: "M8 1.5a6.5 6.5 0 100 13 6.5 6.5 0 000-13zM0 8a8 8 0 1116 0A8 8 0 010 8z"
}), /* @__PURE__ */ import_react.default.createElement("path", {
d: "M7.25 12.026v-1.5h1.5v1.5h-1.5zm.884-7.096A1.125 1.125 0 007.06 6.39l-1.431.448a2.625 2.625 0 115.13-.784c0 .54-.156 1.015-.503 1.488-.3.408-.7.652-.973.818l-.112.068c-.185.116-.26.203-.302.283-.046.087-.097.245-.097.57h-1.5c0-.47.072-.898.274-1.277.206-.385.507-.645.827-.846l.147-.092c.285-.177.413-.257.526-.41.169-.23.213-.397.213-.602 0-.622-.503-1.125-1.125-1.125z"
}));
};
var ConfigRow = (props) => {
console.log(props);
const enabled = !!props.modalConfig[props.storageKey];
const value = props.modalConfig[props.storageKey];
const updateItem = (storageKey, state) => {
props.modalConfig[storageKey] = state;
console.debug(`toggling ${storageKey} to ${state}`);
localStorage.setItem(`library:config:${storageKey}`, String(state));
props.updateConfig(props.modalConfig);
};
const settingsToggleChange = (newValue, storageKey) => {
updateItem(storageKey, newValue);
if (props.callback)
props.callback(newValue);
};
const settingsTextChange = (event) => {
console.log("yoohoo");
updateItem(event.target.dataset.storageKey, event.target.value);
console.log(props.callback);
if (props.callback)
props.callback(event.target.value);
};
const settingsDropdownChange = (event) => {
updateItem(event.target.dataset.storageKey, event.target.value);
if (props.callback)
props.callback(event.target.value);
};
const element = () => {
switch (props.type) {
case "dropdown":
return /* @__PURE__ */ import_react.default.createElement(Dropdown, {
name: props.name,
storageKey: props.storageKey,
value,
options: props.options || [],
onChange: settingsDropdownChange
});
case "text":
return /* @__PURE__ */ import_react.default.createElement(TextInput, {
name: props.name,
storageKey: props.storageKey,
value,
placeholder: props.placeholder,
onChange: settingsTextChange
});
default:
return /* @__PURE__ */ import_react.default.createElement(Spicetify.ReactComponent.Toggle, {
id: `toggle:${props.storageKey}`,
value: enabled,
onSelected: (newValue) => {
settingsToggleChange(newValue, props.storageKey);
}
});
}
};
return /* @__PURE__ */ import_react.default.createElement("div", {
className: "setting-row"
}, /* @__PURE__ */ import_react.default.createElement("label", {
className: "col description"
}, props.name, props.desc && /* @__PURE__ */ import_react.default.createElement(Spicetify.ReactComponent.TooltipWrapper, {
label: /* @__PURE__ */ import_react.default.createElement("div", {
dangerouslySetInnerHTML: { __html: props.desc }
}),
renderInline: true,
showDelay: 10,
placement: "top",
labelClassName: "tooltip",
disabled: false
}, /* @__PURE__ */ import_react.default.createElement("div", {
className: "tooltip-icon"
}, /* @__PURE__ */ import_react.default.createElement(TooltipIcon, null)))), /* @__PURE__ */ import_react.default.createElement("div", {
className: "col action"
}, element()));
};
var SettingsModal = ({ CONFIG, settings, updateAppConfig }) => {
const [modalConfig, setModalConfig] = import_react.default.useState(__spreadValues({}, CONFIG));
const updateConfig = (CONFIG2) => {
updateAppConfig(__spreadValues({}, CONFIG2));
setModalConfig(__spreadValues({}, CONFIG2));
};
const configRows = settings.map((setting, index) => {
console.log(setting);
if (setting.sectionHeader) {
return /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, index != 0 ? /* @__PURE__ */ import_react.default.createElement("br", null) : /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null), /* @__PURE__ */ import_react.default.createElement("h2", {
className: "section-header"
}, setting.sectionHeader), /* @__PURE__ */ import_react.default.createElement(ConfigRow, {
name: setting.name,
storageKey: setting.key,
type: setting.type,
options: setting.options,
placeholder: setting.placeholder,
desc: setting.desc,
modalConfig,
updateConfig,
callback: setting.callback
}));
}
return /* @__PURE__ */ import_react.default.createElement(ConfigRow, {
name: setting.name,
storageKey: setting.key,
type: setting.type,
options: setting.options,
placeholder: setting.placeholder,
desc: setting.desc,
modalConfig,
updateConfig,
callback: setting.callback
});
});
return /* @__PURE__ */ import_react.default.createElement("div", {
id: "stats-config-container"
}, configRows);
};
var settings_modal_default = SettingsModal;
// src/extensions/config_loader.tsx
var import_react2 = __toESM(require_react());
var getLocalStorageDataFromKey = (key, fallback) => {
const data = localStorage.getItem(key);
if (data) {
try {
return JSON.parse(data);
} catch (err) {
return data;
}
} else {
return fallback;
}
};
(function wait() {
const { LocalStorageAPI } = Spicetify == null ? void 0 : Spicetify.Platform;
if (!LocalStorageAPI) {
setTimeout(wait, 100);
return;
}
})();
async function loadConfig(configSettings) {
const { PopupModal } = Spicetify;
await new Promise((resolve) => {
(function checkPopupModal() {
if (PopupModal) {
resolve(void 0);
} else {
setTimeout(checkPopupModal, 100);
}
})();
});
const settingsArray = configSettings.map((setting) => {
return { [setting.key]: getLocalStorageDataFromKey(`library:config:${setting.key}`, setting.def) };
});
let CONFIG = window.CONFIG = Object.assign({}, ...settingsArray);
const updateConfig = (config) => {
window.CONFIG = __spreadValues({}, config);
console.log("updated config", config);
};
const launchModal = window.launchModal = () => {
console.log(settingsArray);
PopupModal.display({
title: "Library Settings",
content: /* @__PURE__ */ import_react2.default.createElement(settings_modal_default, {
CONFIG,
settings: configSettings,
updateAppConfig: updateConfig
}),
isLarge: true
});
};
return { CONFIG, launchModal };
}
var config_loader_default = loadConfig;
return __toCommonJS(config_loader_exports);
})();
})();

View File

@ -0,0 +1,269 @@
(async function() {
while (!Spicetify.React || !Spicetify.ReactDOM) {
await new Promise(resolve => setTimeout(resolve, 10));
}
"use strict";
var library = (() => {
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// external-global-plugin:react
var require_react = __commonJS({
"external-global-plugin:react"(exports, module) {
module.exports = Spicetify.React;
}
});
// src/extensions/config_wrapper.tsx
var config_wrapper_exports = {};
__export(config_wrapper_exports, {
default: () => config_wrapper_default
});
var import_react2 = __toESM(require_react());
// src/components/config/config_modal.tsx
var import_react = __toESM(require_react());
var TextInput = (props) => {
const handleTextChange = (event) => {
props.callback(event.target.value);
};
return /* @__PURE__ */ import_react.default.createElement("label", {
className: "text-input-wrapper"
}, /* @__PURE__ */ import_react.default.createElement("input", {
className: "text-input",
type: "text",
value: props.value || "",
"data-storage-key": props.storageKey,
placeholder: props.placeholder,
id: `text-input:${props.storageKey}`,
title: `Text input for ${props.storageKey}`,
onChange: handleTextChange
}));
};
var Dropdown = (props) => {
const handleDropdownChange = (event) => {
props.callback(event.target.value);
};
return /* @__PURE__ */ import_react.default.createElement("label", {
className: "dropdown-wrapper"
}, /* @__PURE__ */ import_react.default.createElement("select", {
className: "dropdown-input",
value: props.value,
"data-storage-key": props.storageKey,
id: `dropdown:${props.storageKey}`,
title: `Dropdown for ${props.storageKey}`,
onChange: handleDropdownChange
}, props.options.map((option, index) => /* @__PURE__ */ import_react.default.createElement("option", {
key: index,
value: option
}, option))));
};
var ToggleInput = (props) => {
const { Toggle } = Spicetify.ReactComponent;
const handleToggleChange = (newValue) => {
props.callback(newValue);
};
return /* @__PURE__ */ import_react.default.createElement(Toggle, {
id: `toggle:${props.storageKey}`,
value: props.value,
onSelected: (newValue) => handleToggleChange(newValue)
});
};
var SliderInput = (props) => {
const { Slider } = Spicetify.ReactComponent;
const handleSliderChange = (newValue) => {
const calculatedValue = props.min + newValue * (props.max - props.min);
props.callback(calculatedValue);
};
const value = (props.value - props.min) / (props.max - props.min);
return /* @__PURE__ */ import_react.default.createElement(Slider, {
id: `slider:${props.storageKey}`,
value,
min: 0,
max: 1,
step: 0.1,
onDragMove: (newValue) => handleSliderChange(newValue),
onDragStart: () => {
},
onDragEnd: () => {
}
});
};
var TooltipIcon = () => {
return /* @__PURE__ */ import_react.default.createElement("svg", {
role: "img",
height: "16",
width: "16",
className: "Svg-sc-ytk21e-0 uPxdw nW1RKQOkzcJcX6aDCZB4",
viewBox: "0 0 16 16"
}, /* @__PURE__ */ import_react.default.createElement("path", {
d: "M8 1.5a6.5 6.5 0 100 13 6.5 6.5 0 000-13zM0 8a8 8 0 1116 0A8 8 0 010 8z"
}), /* @__PURE__ */ import_react.default.createElement("path", {
d: "M7.25 12.026v-1.5h1.5v1.5h-1.5zm.884-7.096A1.125 1.125 0 007.06 6.39l-1.431.448a2.625 2.625 0 115.13-.784c0 .54-.156 1.015-.503 1.488-.3.408-.7.652-.973.818l-.112.068c-.185.116-.26.203-.302.283-.046.087-.097.245-.097.57h-1.5c0-.47.072-.898.274-1.277.206-.385.507-.645.827-.846l.147-.092c.285-.177.413-.257.526-.41.169-.23.213-.397.213-.602 0-.622-.503-1.125-1.125-1.125z"
}));
};
var ConfigRow = (props) => {
return /* @__PURE__ */ import_react.default.createElement("div", {
className: "setting-row"
}, /* @__PURE__ */ import_react.default.createElement("label", {
className: "col description"
}, props.name, props.desc && /* @__PURE__ */ import_react.default.createElement(Spicetify.ReactComponent.TooltipWrapper, {
label: /* @__PURE__ */ import_react.default.createElement("div", {
dangerouslySetInnerHTML: { __html: props.desc }
}),
renderInline: true,
showDelay: 10,
placement: "top",
labelClassName: "tooltip",
disabled: false
}, /* @__PURE__ */ import_react.default.createElement("div", {
className: "tooltip-icon"
}, /* @__PURE__ */ import_react.default.createElement(TooltipIcon, null)))), /* @__PURE__ */ import_react.default.createElement("div", {
className: "col action"
}, props.children));
};
var ConfigModal = (props) => {
const { config, structure, updateAppConfig } = props;
const [modalConfig, setModalConfig] = import_react.default.useState(__spreadValues({}, config));
const modalRows = structure.map((modalRow, index) => {
const key = modalRow.key;
const currentValue = modalConfig[key];
const updateItem = (state) => {
console.debug(`toggling ${key} to ${state}`);
localStorage.setItem(`library:config:${key}`, String(state));
if (modalRow.callback)
modalRow.callback(state);
const newConfig = __spreadValues({}, modalConfig);
newConfig[key] = state;
updateAppConfig(newConfig);
setModalConfig(newConfig);
};
const header = modalRow.sectionHeader;
const element = () => {
switch (modalRow.type) {
case "toggle":
return /* @__PURE__ */ import_react.default.createElement(ToggleInput, {
storageKey: key,
value: currentValue,
callback: updateItem
});
case "text":
return /* @__PURE__ */ import_react.default.createElement(TextInput, {
storageKey: key,
value: currentValue,
callback: updateItem
});
case "dropdown":
return /* @__PURE__ */ import_react.default.createElement(Dropdown, {
storageKey: key,
value: currentValue,
options: modalRow.options,
callback: updateItem
});
case "slider":
return /* @__PURE__ */ import_react.default.createElement(SliderInput, {
storageKey: key,
value: currentValue,
min: modalRow.min,
max: modalRow.max,
step: modalRow.step,
callback: updateItem
});
}
};
return /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, header && index !== 0 && /* @__PURE__ */ import_react.default.createElement("br", null), header && /* @__PURE__ */ import_react.default.createElement("h2", {
className: "section-header"
}, modalRow.sectionHeader), /* @__PURE__ */ import_react.default.createElement(ConfigRow, {
name: modalRow.name,
desc: modalRow.desc
}, element()));
});
return /* @__PURE__ */ import_react.default.createElement("div", {
id: "library-config-container"
}, modalRows);
};
var config_modal_default = ConfigModal;
// src/extensions/config_wrapper.tsx
var _ConfigWrapper = class {
constructor(modalStructure) {
const config = modalStructure.map((modalStructureRow) => {
var _a;
const value = _ConfigWrapper.getLocalStorageDataFromKey(`library:config:${modalStructureRow.key}`, modalStructureRow.def);
(_a = modalStructureRow.callback) == null ? void 0 : _a.call(modalStructureRow, value);
return { [modalStructureRow.key]: value };
});
this.Config = Object.assign({}, ...config);
this.launchModal = (callback) => {
const updateConfig = (config2) => {
this.Config = __spreadValues({}, config2);
callback == null ? void 0 : callback(config2);
};
Spicetify.PopupModal.display({
title: "Library Settings",
content: /* @__PURE__ */ import_react2.default.createElement(config_modal_default, {
config: this.Config,
structure: modalStructure,
updateAppConfig: updateConfig
}),
isLarge: true
});
};
}
};
var ConfigWrapper = _ConfigWrapper;
ConfigWrapper.getLocalStorageDataFromKey = (key, fallback) => {
const data = localStorage.getItem(key);
if (data) {
try {
return JSON.parse(data);
} catch (err) {
return data;
}
} else {
return fallback;
}
};
var config_wrapper_default = ConfigWrapper;
return __toCommonJS(config_wrapper_exports);
})();
})();

View File

@ -0,0 +1,19 @@
(async function() {
while (!Spicetify.React || !Spicetify.ReactDOM) {
await new Promise(resolve => setTimeout(resolve, 10));
}
"use strict";
var library = (() => {
// src/extensions/context_menu_handler.tsx
var observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.addedNodes.length) {
const node = mutation.addedNodes[0];
console.log(node);
}
});
});
observer.observe(document.body, { childList: true, subtree: false });
})();
})();

View File

@ -0,0 +1,983 @@
(async function() {
while (!Spicetify.React || !Spicetify.ReactDOM) {
await new Promise(resolve => setTimeout(resolve, 10));
}
"use strict";
var library = (() => {
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
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 __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
// external-global-plugin:react
var require_react = __commonJS({
"external-global-plugin:react"(exports, module) {
module.exports = Spicetify.React;
}
});
// external-global-plugin:react-dom
var require_react_dom = __commonJS({
"external-global-plugin:react-dom"(exports, module) {
module.exports = Spicetify.ReactDOM;
}
});
// ../shared/config/config_wrapper.tsx
var import_react2 = __toESM(require_react());
// ../shared/config/config_modal.tsx
var import_react = __toESM(require_react());
var TextInput = (props) => {
const handleTextChange = (event) => {
props.callback(event.target.value);
};
return /* @__PURE__ */ import_react.default.createElement("label", {
className: "text-input-wrapper"
}, /* @__PURE__ */ import_react.default.createElement("input", {
className: "text-input",
type: "text",
value: props.value || "",
"data-storage-key": props.storageKey,
placeholder: props.placeholder,
id: `text-input:${props.storageKey}`,
title: `Text input for ${props.storageKey}`,
onChange: handleTextChange
}));
};
var Dropdown = (props) => {
const handleDropdownChange = (event) => {
props.callback(event.target.value);
};
return /* @__PURE__ */ import_react.default.createElement("label", {
className: "dropdown-wrapper"
}, /* @__PURE__ */ import_react.default.createElement("select", {
className: "dropdown-input",
value: props.value,
"data-storage-key": props.storageKey,
id: `dropdown:${props.storageKey}`,
title: `Dropdown for ${props.storageKey}`,
onChange: handleDropdownChange
}, props.options.map((option, index) => /* @__PURE__ */ import_react.default.createElement("option", {
key: index,
value: option
}, option))));
};
var ToggleInput = (props) => {
const { Toggle } = Spicetify.ReactComponent;
const handleToggleChange = (newValue) => {
props.callback(newValue);
};
return /* @__PURE__ */ import_react.default.createElement(Toggle, {
id: `toggle:${props.storageKey}`,
value: props.value,
onSelected: (newValue) => handleToggleChange(newValue)
});
};
var SliderInput = (props) => {
const { Slider } = Spicetify.ReactComponent;
const handleSliderChange = (newValue) => {
const calculatedValue = props.min + newValue * (props.max - props.min);
props.callback(calculatedValue);
};
const value = (props.value - props.min) / (props.max - props.min);
return /* @__PURE__ */ import_react.default.createElement(Slider, {
id: `slider:${props.storageKey}`,
value,
min: 0,
max: 1,
step: 0.1,
onDragMove: (newValue) => handleSliderChange(newValue),
onDragStart: () => {
},
onDragEnd: () => {
}
});
};
var TooltipIcon = () => {
return /* @__PURE__ */ import_react.default.createElement("svg", {
role: "img",
height: "16",
width: "16",
className: "Svg-sc-ytk21e-0 uPxdw nW1RKQOkzcJcX6aDCZB4",
viewBox: "0 0 16 16"
}, /* @__PURE__ */ import_react.default.createElement("path", {
d: "M8 1.5a6.5 6.5 0 100 13 6.5 6.5 0 000-13zM0 8a8 8 0 1116 0A8 8 0 010 8z"
}), /* @__PURE__ */ import_react.default.createElement("path", {
d: "M7.25 12.026v-1.5h1.5v1.5h-1.5zm.884-7.096A1.125 1.125 0 007.06 6.39l-1.431.448a2.625 2.625 0 115.13-.784c0 .54-.156 1.015-.503 1.488-.3.408-.7.652-.973.818l-.112.068c-.185.116-.26.203-.302.283-.046.087-.097.245-.097.57h-1.5c0-.47.072-.898.274-1.277.206-.385.507-.645.827-.846l.147-.092c.285-.177.413-.257.526-.41.169-.23.213-.397.213-.602 0-.622-.503-1.125-1.125-1.125z"
}));
};
var ConfigRow = (props) => {
return /* @__PURE__ */ import_react.default.createElement("div", {
className: "setting-row"
}, /* @__PURE__ */ import_react.default.createElement("label", {
className: "col description"
}, props.name, props.desc && /* @__PURE__ */ import_react.default.createElement(Spicetify.ReactComponent.TooltipWrapper, {
label: /* @__PURE__ */ import_react.default.createElement("div", {
dangerouslySetInnerHTML: { __html: props.desc }
}),
renderInline: true,
showDelay: 10,
placement: "top",
labelClassName: "tooltip",
disabled: false
}, /* @__PURE__ */ import_react.default.createElement("div", {
className: "tooltip-icon"
}, /* @__PURE__ */ import_react.default.createElement(TooltipIcon, null)))), /* @__PURE__ */ import_react.default.createElement("div", {
className: "col action"
}, props.children));
};
var ConfigModal = (props) => {
const { config, structure, appKey, updateAppConfig } = props;
const [modalConfig, setModalConfig] = import_react.default.useState({ ...config });
const modalRows = structure.map((modalRow, index) => {
const key = modalRow.key;
const currentValue = modalConfig[key];
const updateItem = (state) => {
console.debug(`toggling ${key} to ${state}`);
localStorage.setItem(`${appKey}:config:${key}`, String(state));
if (modalRow.callback)
modalRow.callback(state);
const newConfig = { ...modalConfig };
newConfig[key] = state;
updateAppConfig(newConfig);
setModalConfig(newConfig);
};
const header = modalRow.sectionHeader;
const element = () => {
switch (modalRow.type) {
case "toggle":
return /* @__PURE__ */ import_react.default.createElement(ToggleInput, {
storageKey: key,
value: currentValue,
callback: updateItem
});
case "text":
return /* @__PURE__ */ import_react.default.createElement(TextInput, {
storageKey: key,
value: currentValue,
callback: updateItem
});
case "dropdown":
return /* @__PURE__ */ import_react.default.createElement(Dropdown, {
storageKey: key,
value: currentValue,
options: modalRow.options,
callback: updateItem
});
case "slider":
return /* @__PURE__ */ import_react.default.createElement(SliderInput, {
storageKey: key,
value: currentValue,
min: modalRow.min,
max: modalRow.max,
step: modalRow.step,
callback: updateItem
});
}
};
return /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, header && index !== 0 && /* @__PURE__ */ import_react.default.createElement("br", null), header && /* @__PURE__ */ import_react.default.createElement("h2", {
className: "section-header"
}, modalRow.sectionHeader), /* @__PURE__ */ import_react.default.createElement(ConfigRow, {
name: modalRow.name,
desc: modalRow.desc
}, element()));
});
return /* @__PURE__ */ import_react.default.createElement("div", {
className: "config-container"
}, modalRows);
};
var config_modal_default = ConfigModal;
// ../shared/config/config_wrapper.tsx
var _ConfigWrapper = class {
Config;
launchModal;
constructor(modalStructure, key) {
const config = modalStructure.map((modalStructureRow) => {
const value = _ConfigWrapper.getLocalStorageDataFromKey(
`${key}:config:${modalStructureRow.key}`,
modalStructureRow.def
);
modalStructureRow.callback?.(value);
return { [modalStructureRow.key]: value };
});
this.Config = Object.assign({}, ...config);
this.launchModal = (callback) => {
const updateConfig = (config2) => {
this.Config = { ...config2 };
callback?.(config2);
};
Spicetify.PopupModal.display({
title: `${key.charAt(0).toUpperCase() + key.slice(1)} Settings`,
content: /* @__PURE__ */ import_react2.default.createElement(config_modal_default, {
config: this.Config,
structure: modalStructure,
appKey: key,
updateAppConfig: updateConfig
}),
isLarge: true
});
};
}
};
var ConfigWrapper = _ConfigWrapper;
__publicField(ConfigWrapper, "getLocalStorageDataFromKey", (key, fallback) => {
const data = localStorage.getItem(key);
if (data) {
try {
return JSON.parse(data);
} catch (err) {
return data;
}
} else {
return fallback;
}
});
var config_wrapper_default = ConfigWrapper;
// src/extensions/extension.tsx
var import_react10 = __toESM(require_react());
var import_react_dom = __toESM(require_react_dom());
// src/components/toggle_filters.tsx
var import_react3 = __toESM(require_react());
var UpIcon = () => {
const { IconComponent } = Spicetify.ReactComponent;
return /* @__PURE__ */ import_react3.default.createElement(IconComponent, {
semanticColor: "textSubdued",
dangerouslySetInnerHTML: {
__html: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path d="M.998 8.81A.749.749 0 0 1 .47 7.53L7.99 0l7.522 7.53a.75.75 0 1 1-1.06 1.06L8.74 2.87v12.38a.75.75 0 1 1-1.498 0V2.87L1.528 8.59a.751.751 0 0 1-.53.22z"></path></svg>'
},
iconSize: 16
});
};
var DownIcon = () => {
const { IconComponent } = Spicetify.ReactComponent;
return /* @__PURE__ */ import_react3.default.createElement(IconComponent, {
semanticColor: "textSubdued",
dangerouslySetInnerHTML: {
__html: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path d="M.998 7.19A.749.749 0 0 0 .47 8.47L7.99 16l7.522-7.53a.75.75 0 1 0-1.06-1.06L8.74 13.13V.75a.75.75 0 1 0-1.498 0v12.38L1.528 7.41a.749.749 0 0 0-.53-.22z"></path></svg>'
},
iconSize: 16
});
};
var ToggleFiltersButton = () => {
const [direction, setDirection] = import_react3.default.useState(
document.body.classList.contains("show-ylx-filters") ? "up" : "down"
);
const { ButtonTertiary } = Spicetify.ReactComponent;
const toggleDirection = () => {
if (direction === "down") {
document.body.classList.add("show-ylx-filters");
setDirection("up");
} else {
setDirection("down");
document.body.classList.remove("show-ylx-filters");
}
};
const Icon = direction === "down" ? DownIcon : UpIcon;
return /* @__PURE__ */ import_react3.default.createElement(ButtonTertiary, {
buttonSize: "sm",
"aria-label": "Show Filters",
iconOnly: Icon,
onClick: toggleDirection
});
};
var toggle_filters_default = ToggleFiltersButton;
// src/components/collapse_button.tsx
var import_react4 = __toESM(require_react());
var collapseLibrary = () => {
Spicetify.Platform.LocalStorageAPI.setItem("ylx-sidebar-state", 1);
};
var CollapseIcon = () => {
const { IconComponent } = Spicetify.ReactComponent;
return /* @__PURE__ */ import_react4.default.createElement(IconComponent, {
semanticColor: "textSubdued",
dangerouslySetInnerHTML: {
__html: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path d="M8.81 1A.749.749 0 0 0 7.53.47L0 7.99l7.53 7.521a.75.75 0 0 0 1.234-.815.75.75 0 0 0-.174-.243L2.87 8.74h12.38a.75.75 0 1 0 0-1.498H2.87l5.72-5.713c.14-.14.22-.331.22-.53z"></path></svg>'
},
iconSize: 16
});
};
var CollapseButton = () => {
const { ButtonTertiary } = Spicetify.ReactComponent;
return /* @__PURE__ */ import_react4.default.createElement(ButtonTertiary, {
buttonSize: "sm",
"aria-label": "Show Filters",
iconOnly: CollapseIcon,
onClick: collapseLibrary
});
};
var collapse_button_default = CollapseButton;
// src/components/album_menu_item.tsx
var import_react8 = __toESM(require_react());
// src/components/leading_icon.tsx
var import_react5 = __toESM(require_react());
var LeadingIcon = ({ path }) => {
return /* @__PURE__ */ import_react5.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_react6 = __toESM(require_react());
var TextInputDialog = (props) => {
const { def, placeholder, onSave } = props;
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 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
var getRandomValues;
var rnds8 = new Uint8Array(16);
function rng() {
if (!getRandomValues) {
getRandomValues = typeof crypto !== "undefined" && crypto.getRandomValues && crypto.getRandomValues.bind(crypto);
if (!getRandomValues) {
throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");
}
}
return getRandomValues(rnds8);
}
// ../node_modules/uuid/dist/esm-browser/stringify.js
var byteToHex = [];
for (let i = 0; i < 256; ++i) {
byteToHex.push((i + 256).toString(16).slice(1));
}
function unsafeStringify(arr, offset = 0) {
return byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]];
}
// ../node_modules/uuid/dist/esm-browser/native.js
var randomUUID = typeof crypto !== "undefined" && crypto.randomUUID && crypto.randomUUID.bind(crypto);
var native_default = {
randomUUID
};
// ../node_modules/uuid/dist/esm-browser/v4.js
function v4(options, buf, offset) {
if (native_default.randomUUID && !buf && !options) {
return native_default.randomUUID();
}
options = options || {};
const rnds = options.random || (options.rng || rng)();
rnds[6] = rnds[6] & 15 | 64;
rnds[8] = rnds[8] & 63 | 128;
if (buf) {
offset = offset || 0;
for (let i = 0; i < 16; ++i) {
buf[offset + i] = rnds[i];
}
return buf;
}
return unsafeStringify(rnds);
}
var v4_default = v4;
// src/extensions/collections_wrapper.ts
var _CollectionsWrapper = class extends EventTarget {
_collections;
constructor() {
super();
this._collections = JSON.parse(localStorage.getItem("library:collections") || "[]");
}
saveCollections() {
localStorage.setItem("library:collections", JSON.stringify(this._collections));
this.dispatchEvent(new CustomEvent("update", { detail: this._collections }));
}
getCollection(uri) {
return this._collections.find((collection) => collection.uri === uri);
}
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({
filters: ["0"],
offset: 0,
limit: 9999
});
items.push(...albums.items.filter((album) => collection.items.includes(album.uri)));
return items;
}
async getContents(props) {
const { collectionUri, offset, limit, textFilter } = props;
let items = collectionUri ? await this.getCollectionContents(collectionUri) : this._collections;
const openedCollectionName = collectionUri ? this.getCollection(collectionUri)?.name : void 0;
if (textFilter) {
const regex = new RegExp(`\\b${textFilter}`, "i");
items = items.filter((collection) => regex.test(collection.name));
}
items = items.slice(offset, offset + limit);
return { items, totalLength: this._collections.length, offset, openedCollectionName };
}
async cleanCollections() {
for (const collection of this._collections) {
const boolArray = await Spicetify.Platform.LibraryAPI.contains(...collection.items);
if (boolArray.includes(false)) {
collection.items = collection.items.filter((_, i) => boolArray[i]);
this.saveCollections();
Spicetify.showNotification("Album removed from collection");
this.syncCollection(collection.uri);
}
}
}
async syncCollection(uri) {
const collection = this.getCollection(uri);
if (!collection)
return;
const { PlaylistAPI } = Spicetify.Platform;
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 = "") {
const id = v4_default();
this._collections.push({
type: "collection",
uri: id,
name,
items: [],
addedAt: new Date(),
lastPlayedAt: new Date(),
parentCollection
});
this.saveCollections();
Spicetify.showNotification("Collection created");
return id;
}
deleteCollection(uri) {
this._collections = this._collections.filter((collection) => collection.uri !== uri);
this.saveCollections();
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) {
const collection = this.getCollection(collectionUri);
if (!collection)
return;
await Spicetify.Platform.LibraryAPI.add({ uris: [albumUri] });
collection.items.push(albumUri);
this.saveCollections();
Spicetify.showNotification("Album added to collection");
this.syncCollection(collectionUri);
}
removeAlbumFromCollection(collectionUri, albumUri) {
const collection = this.getCollection(collectionUri);
if (!collection)
return;
collection.items = collection.items.filter((item) => item !== albumUri);
this.saveCollections();
Spicetify.showNotification("Album removed from collection");
this.syncCollection(collectionUri);
}
getCollectionsWithAlbum(albumUri) {
return this._collections.filter((collection) => {
return collection.items.some((item) => item === albumUri);
});
}
renameCollection(uri, name) {
const collection = this.getCollection(uri);
if (!collection)
return;
collection.name = name;
this.saveCollections();
Spicetify.showNotification("Collection renamed");
}
setCollectionImage(uri, url) {
const collection = this.getCollection(uri);
if (!collection)
return;
collection.image = url;
this.saveCollections();
Spicetify.showNotification("Collection image set");
}
removeCollectionImage(uri) {
const collection = this.getCollection(uri);
if (!collection)
return;
collection.image = void 0;
this.saveCollections();
Spicetify.showNotification("Collection image removed");
}
};
var CollectionsWrapper2 = _CollectionsWrapper;
__publicField(CollectionsWrapper2, "INSTANCE", new _CollectionsWrapper());
window.CollectionsWrapper = CollectionsWrapper2.INSTANCE;
// src/extensions/folder_image_wrapper.ts
var _FolderImageWrapper = class extends EventTarget {
_folderImages;
constructor() {
super();
this._folderImages = JSON.parse(localStorage.getItem("library:folderImages") || "{}");
}
getFolderImage(uri) {
return this._folderImages[uri];
}
getFolderImages() {
return this._folderImages;
}
setFolderImage({ uri, url }) {
this._folderImages[uri] = url;
this.saveFolderImages();
Spicetify.showNotification("Folder image updated");
}
removeFolderImage(uri) {
delete this._folderImages[uri];
this.saveFolderImages();
Spicetify.showNotification("Folder image removed");
}
saveFolderImages() {
this.dispatchEvent(new CustomEvent("update", { detail: this._folderImages }));
localStorage.setItem("library:folderImages", JSON.stringify(this._folderImages));
}
};
var FolderImageWrapper2 = _FolderImageWrapper;
__publicField(FolderImageWrapper2, "INSTANCE", new _FolderImageWrapper());
window.FolderImageWrapper = FolderImageWrapper2.INSTANCE;
// src/extensions/extension.tsx
var styleLink = document.createElement("link");
styleLink.rel = "stylesheet";
styleLink.href = "/spicetify-routes-library.css";
document.head.appendChild(styleLink);
var setCardSize = (size) => {
document.documentElement.style.setProperty("--library-card-size", `${size}px`);
};
var setSearchBarSize = (enlarged) => {
const size = enlarged ? 300 : 200;
document.documentElement.style.setProperty("--library-searchbar-size", `${size}px`);
};
var FolderImage = ({ url }) => {
return /* @__PURE__ */ import_react10.default.createElement("img", {
alt: "Folder Image",
"aria-hidden": "true",
draggable: "false",
loading: "eager",
src: url,
className: "main-image-image x-entityImage-image main-image-loading main-image-loaded"
});
};
var FolderPlaceholder = () => {
return /* @__PURE__ */ import_react10.default.createElement("div", {
className: "x-entityImage-imagePlaceholder"
}, /* @__PURE__ */ import_react10.default.createElement("svg", {
"data-encore-id": "icon",
role: "img",
"aria-hidden": "true",
className: "Svg-sc-ytk21e-0 Svg-img-icon-medium",
viewBox: "0 0 24 24"
}, /* @__PURE__ */ import_react10.default.createElement("path", {
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 SpicetifyLibrary = class {
ConfigWrapper = new config_wrapper_default(
[
{
name: "Card Size",
key: "cardSize",
type: "slider",
min: 100,
max: 200,
step: 0.05,
def: 180,
callback: setCardSize
},
{
name: "Extend Search Bar",
key: "extendSearchBar",
type: "toggle",
def: false,
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"
);
};
window.SpicetifyLibrary = new SpicetifyLibrary();
(function wait() {
const { LocalStorageAPI } = Spicetify.Platform;
if (!LocalStorageAPI) {
setTimeout(wait, 100);
return;
}
main(LocalStorageAPI);
})();
function main(LocalStorageAPI) {
const isAlbum = (props) => 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(artist_menu_item_default, null), isArtist);
Spicetify.Platform.LibraryAPI.getEvents()._emitter.addListener("update", () => CollectionsWrapper.cleanCollections());
function injectFolderImages() {
const rootlist = document.querySelector(".main-rootlist-wrapper > div:nth-child(2)");
if (!rootlist)
return setTimeout(injectFolderImages, 100);
setTimeout(() => {
for (const el of Array.from(rootlist.children)) {
const uri = el.querySelector("[aria-labelledby]")?.getAttribute("aria-labelledby")?.slice(14);
if (uri?.includes("folder")) {
const imageBox = el.querySelector(".x-entityImage-imageContainer");
if (!imageBox)
return;
const imageUrl = FolderImageWrapper.getFolderImage(uri);
if (!imageUrl)
import_react_dom.default.render(/* @__PURE__ */ import_react10.default.createElement(FolderPlaceholder, null), imageBox);
else
import_react_dom.default.render(/* @__PURE__ */ import_react10.default.createElement(FolderImage, {
url: imageUrl
}), imageBox);
}
}
}, 500);
}
injectFolderImages();
FolderImageWrapper.addEventListener("update", injectFolderImages);
function injectYLXButtons() {
const ylx_filter = document.querySelector(".main-yourLibraryX-libraryRootlist > .main-yourLibraryX-libraryFilter");
if (!ylx_filter) {
return setTimeout(injectYLXButtons, 100);
}
injectFiltersButton(ylx_filter);
injectCollapseButton(ylx_filter);
}
function injectFiltersButton(ylx_filter) {
const toggleFiltersButton = document.createElement("span");
toggleFiltersButton.classList.add("toggle-filters-button");
ylx_filter.appendChild(toggleFiltersButton);
import_react_dom.default.render(/* @__PURE__ */ import_react10.default.createElement(toggle_filters_default, null), toggleFiltersButton);
}
function injectCollapseButton(ylx_filter) {
const collapseButton = document.createElement("span");
collapseButton.classList.add("collapse-button");
ylx_filter.appendChild(collapseButton);
import_react_dom.default.render(
/* @__PURE__ */ import_react10.default.createElement(Spicetify.ReactComponent.TooltipWrapper, {
label: "Collapse Sidebar",
placement: "top"
}, /* @__PURE__ */ import_react10.default.createElement(collapse_button_default, null)),
collapseButton
);
}
const state = LocalStorageAPI.getItem("ylx-sidebar-state");
if (state === 0)
injectYLXButtons();
LocalStorageAPI.getEvents()._emitter.addListener("update", (e) => {
const { key, value } = e.data;
if (key === "ylx-sidebar-state" && value === 0) {
injectFolderImages();
injectYLXButtons();
}
if (key === "ylx-sidebar-state" && value === 1) {
injectFolderImages();
}
});
}
})();
})();

View File

@ -0,0 +1,69 @@
(async function() {
while (!Spicetify.React || !Spicetify.ReactDOM) {
await new Promise(resolve => setTimeout(resolve, 10));
}
"use strict";
var library = (() => {
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
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) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
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
var folder_image_wrapper_exports = {};
__export(folder_image_wrapper_exports, {
default: () => folder_image_wrapper_default
});
var _FolderImageWrapper = class extends EventTarget {
_folderImages;
constructor() {
super();
this._folderImages = JSON.parse(localStorage.getItem("library:folderImages") || "{}");
}
getFolderImage(uri) {
return this._folderImages[uri];
}
getFolderImages() {
return this._folderImages;
}
setFolderImage({ uri, url }) {
this._folderImages[uri] = url;
this.saveFolderImages();
Spicetify.showNotification("Folder image updated");
}
removeFolderImage(uri) {
delete this._folderImages[uri];
this.saveFolderImages();
Spicetify.showNotification("Folder image removed");
}
saveFolderImages() {
this.dispatchEvent(new CustomEvent("update", { detail: 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;
return __toCommonJS(folder_image_wrapper_exports);
})();
})();

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
{
"name": "Your Library",
"icon": "<svg height=\"24\" width=\"24\" viewBox=\"0 0 24 24\">\r\n<path d=\"M14.5 2.134a1 1 0 0 1 1 0l6 3.464a1 1 0 0 1 .5.866V21a1 1 0 0 1-1 1h-6a1 1 0 0 1-1-1V3a1 1 0 0 1 .5-.866zM16 4.732V20h4V7.041l-4-2.309zM3 22a1 1 0 0 1-1-1V3a1 1 0 0 1 2 0v18a1 1 0 0 1-1 1zm6 0a1 1 0 0 1-1-1V3a1 1 0 0 1 2 0v18a1 1 0 0 1-1 1z\"></path>\r\n</svg>\r\n",
"active-icon": "<svg height=\"24\" width=\"24\" viewBox=\"0 0 24 24\">\r\n<path d=\"M3 22a1 1 0 0 1-1-1V3a1 1 0 0 1 2 0v18a1 1 0 0 1-1 1zM15.5 2.134A1 1 0 0 0 14 3v18a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V6.464a1 1 0 0 0-.5-.866l-6-3.464zM9 2a1 1 0 0 0-1 1v18a1 1 0 1 0 2 0V3a1 1 0 0 0-1-1z\"></path>\r\n</svg>",
"subfiles": [],
"subfiles_extension": [
"collections_wrapper.js",
"extension.js",
"folder_image_wrapper.js"
]
}

View File

@ -0,0 +1,379 @@
/* ../../../AppData/Local/Temp/tmp-4464-wbZ6O1BKhuot/19178f16f304/navBar.module.css */
.navBar-module__topBarHeaderItem___piw4C_library {
-webkit-app-region: no-drag;
display: inline-block;
pointer-events: auto;
}
.navBar-module__topBarHeaderItemLink___xA4uv_library {
margin: 0 8px 0 0;
}
.navBar-module__topBarActive___XhWpm_library {
background-color: var(--spice-tab-active);
border-radius: 4px;
}
.navBar-module__topBarHeaderItemLink___xA4uv_library {
border-radius: 4px;
color: var(--spice-text);
display: inline-block;
margin: 0 8px;
padding: 8px 16px;
position: relative;
text-decoration: none !important;
cursor: pointer;
}
.navBar-module__topBarNav___qWGeZ_library {
-webkit-app-region: drag;
pointer-events: none;
width: 100%;
}
.navBar-module__topBarHeaderItem___piw4C_library .navBar-module__optionsMenuDropBox___pzfNI_library {
color: var(--spice-text);
border: 0;
max-width: 150px;
height: 42px;
padding: 0 30px 0 12px;
background-color: initial;
cursor: pointer;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
.navBar-module__topBarHeaderItem___piw4C_library .navBar-module__optionsMenuDropBox___pzfNI_library svg {
position: absolute;
margin-left: 8px;
}
div.navBar-module__topBarHeaderItemLink___xA4uv_library {
padding: 0;
}
/* ../../../AppData/Local/Temp/tmp-4464-wbZ6O1BKhuot/19178f16dc80/app.css */
:root {
--library-card-size: 180px;
--library-searchbar-size: 200px;
}
#library-app .header-right .x-filterBox-expandedOrHasFilter .x-filterBox-filterInput {
width: var(--library-searchbar-size);
}
#library-app .grid {
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 {
display: flex;
gap: 10px;
flex-direction: column;
justify-content: center;
}
#library-app .load-more-card div:nth-child(2) {
text-align: center;
font-size: var(--encore-text-size-base);
}
#library-app .load-more-card div:first-child {
fill: var(--text-subdued);
width: 80%;
margin: 0 auto;
}
#library-app .load-more-card:hover {
cursor: pointer;
}
.text-input-form {
display: flex;
flex-direction: column;
gap: 18px;
}
.text-input-form .text-input {
background: rgba(var(--spice-rgb-selected-row), 0.1);
border: 1px solid transparent;
border-radius: 4px;
color: var(--spice-text);
font-family: inherit;
font-size: 14px;
height: 32px;
padding: 0 12px;
width: 100%;
}
.text-input-form .text-input:focus {
background-color: var(--spice-tab-active);
border: 1px solid var(--spice-button-disabled);
outline: none;
}
.text-input-form button {
align-self: end;
}
/* ../../../AppData/Local/Temp/tmp-4464-wbZ6O1BKhuot/19178f16ee21/external.css */
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-collapseButton > button:first-child,
.main-yourLibraryX-headerContent > button {
display: none;
}
.main-yourLibraryX-library {
padding-top: 8px;
}
.main-yourLibraryX-header {
margin-top: -8px;
}
.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;
}
.main-yourLibraryX-libraryFilter .main-yourLibraryX-librarySortWrapper,
.main-yourLibraryX-libraryFilter span[role=presentation] {
margin-left: auto;
}
.toggle-filters-button > button:after,
.collapse-button > button:after,
.expand-button > button:after {
display: none;
}
.expand-button {
display: flex;
align-items: center;
z-index: 1;
margin-left: 5px;
}
.expand-button > button {
visibility: hidden;
margin: 0 5px;
}
li.main-yourLibraryX-navItem[data-id="/library"] {
display: flex;
}
li.main-yourLibraryX-navItem[data-id="/library"] > a {
flex-grow: 1;
}
.main-yourLibraryX-libraryFilter .toggle-filters-button > button,
.main-yourLibraryX-libraryFilter .collapse-button > button,
.main-yourLibraryX-libraryFilter .main-yourLibraryX-librarySortWrapper > button,
.main-yourLibraryX-libraryFilter span[role=presentation] span[role=presentation] > button {
padding: 0;
}
.main-yourLibraryX-libraryFilter .toggle-filters-button,
.main-yourLibraryX-libraryFilter .collapse-button,
.main-yourLibraryX-libraryFilter .main-yourLibraryX-librarySortWrapper,
.main-yourLibraryX-libraryFilter span[role=presentation] span[role=presentation] {
display: flex;
flex-basis: 32px;
justify-content: center;
min-width: 24px;
flex-shrink: 10;
}
.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;
}
.LayoutResizer__resize-bar {
opacity: 0 !important;
}
.Root__nav-bar .x-filterBox-expandedOrHasFilter .x-filterBox-filterInput {
width: 100%;
}
.Root__nav-bar .x-filterBox-expandedOrHasFilter {
flex-grow: 1;
margin-right: 5px;
}
.Root__nav-bar:has(> .LayoutResizer__resize-bar:hover) .expand-button > button,
.Root__nav-bar .expand-button:hover > button {
visibility: visible;
height: 32px;
background-color: black;
}
.text-input-form .Button-small-buttonPrimary {
box-sizing: border-box;
-webkit-tap-highlight-color: transparent;
font-size: 0.875rem;
font-weight: 700;
font-family: var(--font-family, CircularSp, CircularSp-Arab, CircularSp-Hebr, CircularSp-Cyrl, CircularSp-Grek, CircularSp-Deva, var(--fallback-fonts, sans-serif));
background-color: transparent;
border: 0px;
border-radius: 9999px;
cursor: pointer;
display: inline-block;
position: relative;
text-align: center;
text-decoration: none;
text-transform: none;
touch-action: manipulation;
transition-duration: 33ms;
transition-property:
background-color,
border-color,
color,
box-shadow,
filter,
transform;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
vertical-align: middle;
transform: translate3d(0px, 0px, 0px);
padding: 0px;
min-inline-size: 0px;
}
.text-input-form .ButtonInner-small {
box-sizing: border-box;
-webkit-tap-highlight-color: transparent;
position: relative;
background-color: var(--background-base, #1ed760);
color: var(--text-base, #000000);
display: flex;
border-radius: 9999px;
font-size: inherit;
min-block-size: var(--encore-control-size-smaller, 32px);
align-items: center;
justify-content: center;
padding-block-start: var(--encore-spacing-tighter-4, 4px);
padding-block-end: var(--encore-spacing-tighter-4, 4px);
padding-inline-start: var(--encore-spacing-base, 16px);
padding-inline-end: var(--encore-spacing-base, 16px);
}
.text-input-form .Button-small-buttonPrimary:hover .ButtonInner-sc-14ud5tc-0,
.text-input-form .Button-small-buttonPrimary:hover .ButtonFocus-sc-2hq6ey-0 {
transform: scale(1.04);
}
/* ../../../AppData/Local/Temp/tmp-4464-wbZ6O1BKhuot/19178f16f0a2/config_modal.css */
.config-container {
gap: 10px;
display: flex;
flex-direction: column;
}
.config-container .section-header {
box-sizing: border-box;
-webkit-tap-highlight-color: transparent;
margin-block: 0px;
font-size: 1.125rem;
font-weight: 700;
color: var(--spice-text);
}
.config-container .col.description {
box-sizing: border-box;
-webkit-tap-highlight-color: transparent;
margin-block: 0px;
font-size: 0.875rem;
font-weight: 400;
color: var(--spice-subtext);
}
.config-container .disabled {
opacity: 0;
pointer-events: none;
}
.config-container .text-input {
background: rgba(var(--spice-rgb-selected-row), 0.1);
border: 1px solid transparent;
border-radius: 4px;
color: var(--spice-text);
font-family: inherit;
font-size: 14px;
height: 32px;
padding: 0 12px;
width: 100%;
}
.config-container .text-input:focus {
background-color: var(--spice-tab-active);
border: 1px solid var(--spice-button-disabled);
outline: none;
}
.config-container .dropdown-input {
background-color: var(--spice-tab-active);
border: 0;
border-radius: 4px;
color: rgba(var(--spice-rgb-selected-row), 0.7);
font-size: 14px;
font-weight: 400;
height: 32px;
letter-spacing: 0.24px;
line-height: 20px;
padding: 0 32px 0 12px;
width: 100%;
}
.config-container .tooltip-icon {
float: right;
margin-left: 10px;
display: flex;
align-items: center;
height: 22px;
fill: var(--spice-subtext);
}
.config-container .tooltip-icon:hover {
fill: var(--spice-text);
}
.config-container .tooltip {
text-align: center;
}
.config-container .setting-row {
display: flex;
justify-content: space-between;
}
.config-container .playback-progressbar {
width: 200px;
}
/* ../../../AppData/Local/Temp/tmp-4464-wbZ6O1BKhuot/19178f16f163/shared.css */
.grid {
--grid-gap: 24px;
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)) !important;
}
.loadingWrapper {
display: flex;
justify-content: center;
align-items: center;
min-height: 60vh;
flex-direction: column;
gap: 16px;
}
.loadingWrapper .status-icon {
width: 40px;
height: 40px;
fill: currentColor;
}
.page-content {
display: flex;
flex-direction: column;
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 {
align-content: space-between;
align-items: center;
display: flex;
justify-content: space-between;
margin: 16px 0;
}
.page-header .header-right,
.page-header .header-left {
display: flex;
align-items: center;
gap: 8px;
}
.page-header .header-right {
justify-content: flex-end;
}
.page-header .header-left {
justify-content: flex-start;
}
.new-update {
background-color: var(--spice-player);
color: var(--spice-text);
border-radius: 8px;
padding: 2px 12px;
margin: 0 24px;
border: 0px;
}

View File

@ -0,0 +1,35 @@
# Spicetify Marketplace
<p>
<a href="https://github.com/spicetify/spicetify-marketplace/releases/latest">
<img src="https://img.shields.io/github/v/release/spicetify/spicetify-marketplace?include_prereleases">
</a>
<a href="https://github.com/spicetify/spicetify-marketplace/releases">
<img src="https://img.shields.io/github/downloads/spicetify/spicetify-marketplace/total.svg">
</a>
<a href="https://github.com/spicetify/spicetify-marketplace/issues?q=is%3Aissue+is%3Aclosed">
<img src="https://img.shields.io/github/issues-closed/spicetify/spicetify-marketplace">
</a>
<a href="https://github.com/spicetify/spicetify-marketplace/commits/main">
<img src="https://img.shields.io/github/commit-activity/m/spicetify/spicetify-marketplace">
</a>
</p>
Customize your Spotify client directly from within [Spicetify](https://github.com/spicetify/spicetify-cli)!
Marketplace allows you to **browse, download, and install** extensions, themes, and CSS snippets with ease. You can also browse custom apps, but will need to do some manual installation to get them working.
Made with [Spicetify Creator](https://github.com/spicetify/spicetify-creator)
Head to the [wiki](https://github.com/spicetify/spicetify-marketplace/wiki) to get started!
---
## Links
- [Overview](https://github.com/spicetify/spicetify-marketplace/wiki)
- [Installation](https://github.com/spicetify/spicetify-marketplace/wiki/Installation)
- [Publishing to Marketplace](https://github.com/spicetify/spicetify-marketplace/wiki/Publishing-to-Marketplace)
- [Contributions](https://github.com/spicetify/spicetify-marketplace/wiki/Contributions)
- [Development](https://github.com/spicetify/spicetify-marketplace/wiki/Development)
- [Translating/Localizing Marketplace](https://github.com/spicetify/spicetify-marketplace/wiki/Localizing-Marketplace)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,12 @@
{
"name": {
"en": "Marketplace",
"ru": "Маркетплейс"
},
"icon": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"100%\" height=\"100%\" viewBox=\"0 0 76.465 68.262\"><path d=\"M151.909 72.923v6.5h10.097l8.663 44.567h48.968v-6.5h-43.61l-1.2-6.172h42.974l10.35-33.91h-59.915l-.872-4.485H151.91zm17.59 10.984h49.867l-6.393 20.91h-39.409l-4.064-20.91zm5.626 44.11a6.5 6.5 0 0 0-6.5 6.5 6.5 6.5 0 0 0 6.5 6.501 6.5 6.5 0 0 0 6.5-6.5 6.5 6.5 0 0 0-6.5-6.5zm38.274 0a6.5 6.5 0 0 0-6.5 6.5 6.5 6.5 0 0 0 6.5 6.501 6.5 6.5 0 0 0 6.5-6.5 6.5 6.5 0 0 0-6.5-6.5z\" style=\"fill:currentColor;stroke-width:.264583\" transform=\"translate(-151.909 -72.923)\"/></svg>\n",
"active-icon": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"100%\" height=\"100%\" viewBox=\"0 0 76.465 68.262\"><path d=\"M151.909 72.923v6.5h10.097l8.663 44.567h48.968v-6.5h-43.61l-1.2-6.172h42.974l10.35-33.91h-59.915l-.872-4.485H151.91zm23.216 55.095a6.5 6.5 0 0 0-6.5 6.5 6.5 6.5 0 0 0 6.5 6.5 6.5 6.5 0 0 0 6.5-6.5 6.5 6.5 0 0 0-6.5-6.5zm38.274 0a6.5 6.5 0 0 0-6.5 6.5 6.5 6.5 0 0 0 6.5 6.5 6.5 6.5 0 0 0 6.5-6.5 6.5 6.5 0 0 0-6.5-6.5z\" style=\"fill:currentColor;stroke-width:.264583\" transform=\"translate(-151.909 -72.923)\"/></svg>\n",
"subfiles": [],
"subfiles_extension": [
"extension.js"
]
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,66 @@
(async function() {
while (!Spicetify.React || !Spicetify.ReactDOM) {
await new Promise(resolve => setTimeout(resolve, 10));
}
"use strict";
var stats = (() => {
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/extensions/cache.ts
var cache_exports = {};
__export(cache_exports, {
batchCacher: () => batchCacher,
cacher: () => cacher,
invalidator: () => invalidator,
set: () => set
});
var cache = {};
var set = (key, value) => {
cache[key] = value;
};
var invalidate = (key) => {
delete cache[key];
};
var cacher = (cb) => {
return async ({ queryKey }) => {
const key = queryKey.join("-");
if (cache[key])
return cache[key];
const result = await cb();
set(key, result);
return result;
};
};
var batchCacher = (prefix, cb) => {
return async (ids) => {
const cached = ids.map((id) => cache[`${prefix}-${id}`]);
const uncached = ids.filter((_, index) => !cached[index]);
const results = await cb(uncached);
results.forEach((result, index) => set(`${prefix}-${uncached[index]}`, result));
return [...cached.filter(Boolean), ...results];
};
};
var invalidator = (queryKey, refetch) => {
invalidate(queryKey.join("-"));
refetch();
};
return __toCommonJS(cache_exports);
})();
})();

View File

@ -0,0 +1,76 @@
/* ../../../AppData/Local/Temp/tmp-15744-866d0PjWRxih/18d53b11b111/config_modal.css */
#config-container {
gap: 10px;
display: flex;
flex-direction: column;
}
#config-container .section-header {
box-sizing: border-box;
-webkit-tap-highlight-color: transparent;
margin-block: 0px;
font-size: 1.125rem;
font-weight: 700;
color: var(--spice-text);
}
#config-container .col.description {
box-sizing: border-box;
-webkit-tap-highlight-color: transparent;
margin-block: 0px;
font-size: 0.875rem;
font-weight: 400;
color: var(--spice-subtext);
}
#config-container .disabled {
opacity: 0;
pointer-events: none;
}
#config-container .text-input {
background: rgba(var(--spice-rgb-selected-row), 0.1);
border: 1px solid transparent;
border-radius: 4px;
color: var(--spice-text);
font-family: inherit;
font-size: 14px;
height: 32px;
padding: 0 12px;
width: 100%;
}
#config-container .text-input:focus {
background-color: var(--spice-tab-active);
border: 1px solid var(--spice-button-disabled);
outline: none;
}
#config-container .dropdown-input {
background-color: var(--spice-tab-active);
border: 0;
border-radius: 4px;
color: rgba(var(--spice-rgb-selected-row), 0.7);
font-size: 14px;
font-weight: 400;
height: 32px;
letter-spacing: 0.24px;
line-height: 20px;
padding: 0 32px 0 12px;
width: 100%;
}
#config-container .tooltip-icon {
float: right;
margin-left: 10px;
display: flex;
align-items: center;
height: 22px;
fill: var(--spice-subtext);
}
#config-container .tooltip-icon:hover {
fill: var(--spice-text);
}
#config-container .tooltip {
text-align: center;
}
#config-container .setting-row {
display: flex;
justify-content: space-between;
}
#config-container .playback-progressbar {
width: 200px;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,10 @@
{
"name": "Statistics",
"icon": "<svg xmlns=\"http://www.w3.org/2000/svg\"\r\n\t width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" style=\"fill:currentColor\" >\r\n<path d=\"M3,23L3,23c-0.55,0-1-0.45-1-1v-9c0-0.55,0.45-1,1-1h0c0.55,0,1,0.45,1,1v9C4,22.55,3.55,23,3,23z\"/>\r\n<path d=\"M9,23L9,23c-0.55,0-1-0.45-1-1V9c0-0.55,0.45-1,1-1h0c0.55,0,1,0.45,1,1v13C10,22.55,9.55,23,9,23z\"/>\r\n<path d=\"M15,23L15,23c-0.55,0-1-0.45-1-1V11c0-0.55,0.45-1,1-1h0c0.55,0,1,0.45,1,1v11C16,22.55,15.55,23,15,23z\"/>\r\n<path d=\"M21,23L21,23c-0.55,0-1-0.45-1-1V8c0-0.55,0.45-1,1-1h0c0.55,0,1,0.45,1,1v14C22,22.55,21.55,23,21,23z\"/>\r\n<path d=\"M22.86,1.5c-0.28-0.48-0.89-0.64-1.37-0.37l-6.54,3.74l-6-2.33C8.52,2.38,8.22,2.41,7.88,2.73L1.29,7.71\r\n\tC0.86,8.05,0.8,8.68,1.15,9.11s0.98,0.49,1.41,0.14l6.2-4.65l5.69,2.2C15,6.99,15.3,6.96,15.83,6.68l6.67-3.82\r\n\tC22.98,2.59,23.14,1.97,22.86,1.5z\"/>\r\n</svg>\r\n",
"active-icon": "<svg xmlns=\"http://www.w3.org/2000/svg\"\r\n\t width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" style=\"fill:currentColor\" >\r\n<path d=\"M3,23L3,23c-0.55,0-1-0.45-1-1v-9c0-0.55,0.45-1,1-1h0c0.55,0,1,0.45,1,1v9C4,22.55,3.55,23,3,23z\"/>\r\n<path d=\"M9,23L9,23c-0.55,0-1-0.45-1-1V9c0-0.55,0.45-1,1-1h0c0.55,0,1,0.45,1,1v13C10,22.55,9.55,23,9,23z\"/>\r\n<path d=\"M15,23L15,23c-0.55,0-1-0.45-1-1V11c0-0.55,0.45-1,1-1h0c0.55,0,1,0.45,1,1v11C16,22.55,15.55,23,15,23z\"/>\r\n<path d=\"M21,23L21,23c-0.55,0-1-0.45-1-1V8c0-0.55,0.45-1,1-1h0c0.55,0,1,0.45,1,1v14C22,22.55,21.55,23,21,23z\"/>\r\n<path d=\"M22.86,1.5c-0.28-0.48-0.89-0.64-1.37-0.37l-6.54,3.74l-6-2.33C8.52,2.38,8.22,2.41,7.88,2.73L1.29,7.71\r\n\tC0.86,8.05,0.8,8.68,1.15,9.11s0.98,0.49,1.41,0.14l6.2-4.65l5.69,2.2C15,6.99,15.3,6.96,15.83,6.68l6.67-3.82\r\n\tC22.98,2.59,23.14,1.97,22.86,1.5z\"/>\r\n</svg>\r\n",
"subfiles": [],
"subfiles_extension": [
"cache.js",
"extension.js"
]
}

View File

@ -0,0 +1,315 @@
/* ../../../AppData/Local/Temp/tmp-2132-C1IXGV9b5FdF/191733900bf3/navBar.module.css */
.navBar-module__topBarHeaderItem___piw4C_stats {
-webkit-app-region: no-drag;
display: inline-block;
pointer-events: auto;
}
.navBar-module__topBarHeaderItemLink___xA4uv_stats {
margin: 0 8px 0 0;
}
.navBar-module__topBarActive___XhWpm_stats {
background-color: var(--spice-tab-active);
border-radius: 4px;
}
.navBar-module__topBarHeaderItemLink___xA4uv_stats {
border-radius: 4px;
color: var(--spice-text);
display: inline-block;
margin: 0 8px;
padding: 8px 16px;
position: relative;
text-decoration: none !important;
cursor: pointer;
}
.navBar-module__topBarNav___qWGeZ_stats {
-webkit-app-region: drag;
pointer-events: none;
width: 100%;
}
.navBar-module__topBarHeaderItem___piw4C_stats .navBar-module__optionsMenuDropBox___pzfNI_stats {
color: var(--spice-text);
border: 0;
max-width: 150px;
height: 42px;
padding: 0 30px 0 12px;
background-color: initial;
cursor: pointer;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
.navBar-module__topBarHeaderItem___piw4C_stats .navBar-module__optionsMenuDropBox___pzfNI_stats svg {
position: absolute;
margin-left: 8px;
}
div.navBar-module__topBarHeaderItemLink___xA4uv_stats {
padding: 0;
}
/* ../../../AppData/Local/Temp/tmp-2132-C1IXGV9b5FdF/1917338fb020/app.css */
#stats-app .stats-gridInline {
--grid-gap: 24px;
grid-template-columns: repeat(10, 180px) !important;
overflow-x: hidden;
scroll-behavior: smooth;
margin-top: 5px;
}
#stats-app .grid:nth-child(2) {
margin-top: 24px;
}
#stats-app [data-scroll=both] {
-webkit-mask-image: linear-gradient(to right, transparent, black 10%, black 90%, transparent);
mask-image: linear-gradient(to right, transparent, black 10%, black 90%, transparent);
}
#stats-app [data-scroll=end] {
-webkit-mask-image: linear-gradient(to right, transparent, black 10%);
mask-image: linear-gradient(to right, transparent, black 10%);
}
#stats-app [data-scroll=start] {
-webkit-mask-image: linear-gradient(to right, black 90%, transparent);
mask-image: linear-gradient(to right, black 90%, transparent);
}
#stats-app .stats-libraryOverview {
display: flex;
gap: 24px;
align-items: center;
}
#stats-app .stats-trackPageTitle {
display: flex;
gap: 24px;
align-items: center;
}
#stats-app .stats-scrollButton {
width: 40px;
border-radius: 8px;
border: none;
padding: 0;
margin-right: 5px;
background-color: var(--spice-player);
color: var(--spice-subtext);
}
#stats-app .stats-scrollButton:hover {
background-color: var(--spice-card);
color: var(--spice-text);
}
#stats-app .stats-tracklistHeader > div {
display: flex;
-webkit-app-region: no-drag;
gap: 20px;
align-items: center;
}
#stats-app .stats-make-playlist-button {
margin-inline-start: 12px;
}
#stats-app .stats-genreCard {
display: flex;
flex-direction: column;
gap: 10px;
padding: 16px;
border-radius: 8px;
background: var(--spice-player);
position: relative;
}
#stats-app .stats-genreRow {
width: 100%;
height: 20px;
display: flex;
gap: 10px;
}
#stats-app .stats-genreRowFill {
background: var(--spice-button);
height: 100%;
border-radius: 8px;
display: flex;
align-items: center;
}
#stats-app .stats-genreText {
color: var(--spice-player);
font-size: 0.875rem;
margin-left: 7px;
font-weight: bold;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
#stats-app .stats-genreValue {
color: var(--spice-text);
font-size: 0.875rem;
}
#stats-app .stats-genreCard + .stats-gridInlineSection {
margin-top: 3px;
}
#stats-app .main-trackList-rowHeartButton,
#stats-app .main-trackList-rowMoreButton {
background-color: transparent;
border: none;
}
#stats-app .main-trackList-rowPlayPauseIcon {
fill: currentColor;
}
#stats-app .extend-button {
background-color: transparent;
border: none;
position: absolute;
right: 20px;
bottom: 20px;
font-size: 14px;
color: var(--spice-subtext);
}
#stats-app .extend-button:hover {
color: var(--spice-text);
}
#stats-app .main-card-cardContainer {
width: 100%;
height: 100%;
}
.GenericModal[aria-label="Playlist Stats"] .main-embedWidgetGenerator-container {
width: 80vw;
height: 80vh;
background-color: var(--spice-main);
}
.GenericModal[aria-label="Playlist Stats"] .main-shelf-title {
color: var(--spice-text);
}
/* ../../../AppData/Local/Temp/tmp-2132-C1IXGV9b5FdF/1917338ffe31/config_modal.css */
.config-container {
gap: 10px;
display: flex;
flex-direction: column;
}
.config-container .section-header {
box-sizing: border-box;
-webkit-tap-highlight-color: transparent;
margin-block: 0px;
font-size: 1.125rem;
font-weight: 700;
color: var(--spice-text);
}
.config-container .col.description {
box-sizing: border-box;
-webkit-tap-highlight-color: transparent;
margin-block: 0px;
font-size: 0.875rem;
font-weight: 400;
color: var(--spice-subtext);
}
.config-container .disabled {
opacity: 0;
pointer-events: none;
}
.config-container .text-input {
background: rgba(var(--spice-rgb-selected-row), 0.1);
border: 1px solid transparent;
border-radius: 4px;
color: var(--spice-text);
font-family: inherit;
font-size: 14px;
height: 32px;
padding: 0 12px;
width: 100%;
}
.config-container .text-input:focus {
background-color: var(--spice-tab-active);
border: 1px solid var(--spice-button-disabled);
outline: none;
}
.config-container .dropdown-input {
background-color: var(--spice-tab-active);
border: 0;
border-radius: 4px;
color: rgba(var(--spice-rgb-selected-row), 0.7);
font-size: 14px;
font-weight: 400;
height: 32px;
letter-spacing: 0.24px;
line-height: 20px;
padding: 0 32px 0 12px;
width: 100%;
}
.config-container .tooltip-icon {
float: right;
margin-left: 10px;
display: flex;
align-items: center;
height: 22px;
fill: var(--spice-subtext);
}
.config-container .tooltip-icon:hover {
fill: var(--spice-text);
}
.config-container .tooltip {
text-align: center;
}
.config-container .setting-row {
display: flex;
justify-content: space-between;
}
.config-container .playback-progressbar {
width: 200px;
}
/* ../../../AppData/Local/Temp/tmp-2132-C1IXGV9b5FdF/1917338fffd2/shared.css */
.grid {
--grid-gap: 24px;
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)) !important;
}
.loadingWrapper {
display: flex;
justify-content: center;
align-items: center;
min-height: 60vh;
flex-direction: column;
gap: 16px;
}
.loadingWrapper .status-icon {
width: 40px;
height: 40px;
fill: currentColor;
}
.page-content {
display: flex;
flex-direction: column;
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 {
align-content: space-between;
align-items: center;
display: flex;
justify-content: space-between;
margin: 16px 0;
}
.page-header .header-right,
.page-header .header-left {
display: flex;
align-items: center;
gap: 8px;
}
.page-header .header-right {
justify-content: flex-end;
}
.page-header .header-left {
justify-content: flex-start;
}
.new-update {
background-color: var(--spice-player);
color: var(--spice-text);
border-radius: 8px;
padding: 2px 12px;
margin: 0 24px;
border: 0px;
}

View File

@ -0,0 +1,53 @@
{
"desktop-auth.login.millions-of-songs": "Miljoonittain kappaleita.",
"desktop-auth.login.free-on-spotify": "A Spotifyon ingyen hallgathatod őket.",
"desktop-auth.login.collect-and-create": "Συλλογή και δημιουργία. Δημιούργησε μια προσωπική βιβλιοθήκη με την αγαπημένη σου μουσική και τον αγαπημένο σου ήχο.",
"desktop-auth.login.perfect-work-environment": "മികച്ച തൊഴിൽ അന്തരീക്ഷം സൃഷ്‌ടിക്കുക. Spotify പ്ലേലിസ്റ്റുകൾ ഉപയോഗിച്ച് നിങ്ങളുടെ ഉൽപ്പാദനക്ഷമത സമൃദ്ധമാക്കുക.",
"desktop.login.PreferencesLink": "Indstillinger",
"desktop-auth.login.preview-experience": "Confira uma prévia da experiência",
"desktop-auth.login.sign-up-with-browser": "Regista-te já gratuitamente",
"desktop-auth.login.log-in-with-browser": "Ingia katika akaunti",
"close": "बन्द गर्नुहोस्",
"desktop-auth.login.go-to-browser-signup": "Μετάβαση στο πρόγραμμα περιήγησης για συνέχεια",
"desktop-auth.login.go-to-browser-login": "Nenda kwenye kivinjari chako ili uingie katika akaunti",
"desktop-auth.login.not-seeing-browser": "Δεν βλέπεις την καρτέλα στο πρόγραμμα περιήγησης;",
"desktop-auth.login.try-again": "மீண்டும் முயற்சி செய்க",
"desktop-auth.login.new-to-spotify": "Spotifyని ఇప్పుడే కొత్తగా ఉపయోగిస్తున్నారా?",
"desktop.login.Back": "पछाडि जानुहोस्",
"desktop-auth.login.redirect-to-browser-signup": "Du wirst zum Browser weitergeleitet, um die Registrierung abzuschließen.",
"desktop-auth.login.redirect-to-browser-login": "Te estamos redirigiendo a un navegador para completar el inicio de sesión",
"desktop-auth.login.signup-time-out": "Se ha agotado el tiempo del proceso de registro; inténtalo de nuevo",
"desktop-auth.login.login-time-out": "Se ha agotado el tiempo del proceso de inicio de sesión; inténtalo de nuevo",
"page.loading": "Caricamento in corso",
"desktop.settings.proxy.title": "Configuració del servidor intermediari",
"desktop.settings.proxy.type": "Tipus de servidor intermediari",
"desktop.settings.proxy.host": "Πάροχος φιλοξενίας",
"desktop.settings.proxy.port": "পোর্ট করুন",
"desktop.settings.proxy.user": "Erabiltzaile-izena",
"desktop.settings.proxy.pass": "Κωδικός πρόσβασης",
"desktop.login.UnknownLoginErrorMessage": "Der Dienst ist vorübergehend nicht verfügbar. Bitte versuch es später noch mal.",
"desktop.login.DefaultErrorMessage": "Ένα τείχος προστασίας ενδέχεται να αποκλείει το Spotify. Ενημέρωσε το τείχος προστασίας σου για να μην αποκλείει το Spotify. Επιπλέον, μπορείς να δοκιμάσεις να αλλάξεις τις τρέχουσες <a href=\"#\" data-action=\"%0%\">ρυθμίσεις διακομιστή μεσολάβησης</a>.",
"desktop.login.SessionTerminatedMessage": "നിങ്ങളുടെ സെഷൻ അവസാനിപ്പിച്ചിരിക്കുന്നു",
"desktop.login.SessionExpiredMessage": "ਤੁਹਾਡੇ ਸੈਸ਼ਨ ਦੀ ਮਿਆਦ ਸਮਾਪਤ ਹੋ ਗਈ ਹੈ, ਕਿਰਪਾ ਕਰਕੇ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।",
"desktop.login.BadCredentialsMessage": "O nome de utilizador ou a palavra-passe estão incorretos.",
"desktop.login.ErrorResolvingDNS": "Der blev ikke registreret nogen internetforbindelse.",
"desktop.login.ErrorProxyUnauthorized": "നിങ്ങളുടെ ഇന്റർനെറ്റ് നെറ്റ്‌വർക്ക് Spotify-യെ തടയുന്നു. ആക്‌സസ് ലഭിക്കാൻ നിങ്ങളുടെ നെറ്റ്‌വർക്ക് അഡ്‌മിനിസ്‌ട്രേറ്ററെ ബന്ധപ്പെടുക.",
"desktop.login.ErrorProxyForbidden": "നിങ്ങളുടെ ഇന്റർനെറ്റ് നെറ്റ്‌വർക്ക് Spotify-യെ തടയുന്നു. ആക്‌സസ് ലഭിക്കാൻ നിങ്ങളുടെ നെറ്റ്‌വർക്ക് അഡ്‌മിനിസ്‌ട്രേറ്ററെ ബന്ധപ്പെടുക.",
"desktop.login.ErrorProxyAuthRequired": "La teva connexió a Internet està bloquejant Spotify. Posa't en contacte amb l'administrador de la xarxa o canvia la <a href=\"#\" data-action=\"%0%\">configuració del servidor intermediari</a>.",
"desktop.login.CriticalUpdate": "Une mise à jour de votre client est en cours.",
"desktop.login.UserBannedMessage": "Selle konto kasutamine on keelatud.",
"desktop.login.UserNotAllowedOnPlatformMessage": "Η χρήση αυτής της συσκευής δεν είναι ενεργοποιημένη για τον λογαριασμό σου.",
"desktop.login.MissingUserInfoMessage": "Le profil de l'utilisateur nest pas entièrement à jour, <a href=\"%0%\">mettez votre profil à jour</a> , déconnectez-vous, puis connectez-vous une nouvelle fois.",
"desktop.login.RegionMismatchMessage": "നിങ്ങളുടെ പ്രൊഫൈലിൽ സജ്ജീകരിച്ചിരിക്കുന്നതുമായി നിങ്ങളുടെ രാജ്യം പൊരുത്തപ്പെടുന്നില്ല. ഉപയോഗം തുടരാൻ, <a href=\"%0%\">നിങ്ങളുടെ പ്രൊഫൈൽ അപ്ഡേറ്റ് ചെയ്യുക</a> അല്ലെങ്കിൽ <a href=\"%1%\">നിങ്ങളുടെ Spotify അക്കൗണ്ട് അപ്ഗ്രേഡ് ചെയ്യുക</a>.",
"desktop.login.PremiumUsersOnlyMessage": "ഈ ആപ്പ് Premium ഉപയോക്താക്കൾക്ക് മാത്രമായി പരിമിതപ്പെടുത്തിയിരിക്കുന്നു.",
"desktop.login.CreateUserDeniedMessage": "Diese E-Mail-Adresse ist bereits mit einem/einer anderen Nutzer*in verbunden.",
"desktop.login.ClientUpdateFail": "Spotify വെബ്‌സൈറ്റിൽ നിന്ന് <a href=\"%0%\">ഏറ്റവും പുതിയ പതിപ്പ്</a> ഡൗൺലോഡ് ചെയ്യുക.",
"desktop.login.FbUserNotFoundSignUp": "നിങ്ങളുടെ Facebook അക്കൗണ്ടിലേക്ക് ഒരു Spotify അക്കൗണ്ട് കണക്‌റ്റ് ചെയ്‌തിട്ടില്ല. നിങ്ങൾക്ക് ഒരു Spotify അക്കൗണ്ട് ഉണ്ടെങ്കിൽ, Spotify ക്രെഡൻഷ്യലുകൾ ഉപയോഗിച്ച് ലോഗിൻ ചെയ്യുക. നിങ്ങൾക്ക് ഒരു Spotify അക്കൗണ്ട് ഇല്ലെങ്കിൽ, <a href=\"#\" data-action=\"%0%\">സൈനപ്പ് ചെയ്യുക</a>.",
"desktop.login.errorCode": "(Msimbo wa hitilafu: {0})",
"desktop.settings.proxy.autodetect": "स्वतः पत्ता लगाउने सुविधासम्बन्धी सेटिङ",
"desktop.settings.proxy.noproxy": "Χωρίς διακομιστή μεσολάβησης",
"desktop.settings.proxy.http": "ኤችቲቲፒ",
"desktop.settings.proxy.socks4": "بروتوكول إنترنت SOCKS4",
"desktop.settings.proxy.socks5": "بروتوكول إنترنت SOCKS5",
"settings.restartApp": "Käynnistä sovellus uudelleen"
}

View File

@ -0,0 +1,53 @@
{
"desktop-auth.login.millions-of-songs": "Miljoene liedjies.",
"desktop-auth.login.free-on-spotify": "Gratis op Spotify.",
"desktop-auth.login.collect-and-create": "Versamel en skep. Bou n persoonlike biblioteek van jou gunstelingmusiek en -klank.",
"desktop-auth.login.perfect-work-environment": "Skep die perfekte werksomgewing. Verbeter jou produktiwiteit met Spotify-speellyste.",
"desktop.login.PreferencesLink": "Instellings",
"desktop-auth.login.preview-experience": "Voorbeskou die ervaring",
"desktop-auth.login.sign-up-with-browser": "Registreer gratis",
"desktop-auth.login.log-in-with-browser": "Meld aan",
"close": "Maak toe",
"desktop-auth.login.go-to-browser-signup": "Gaan na jou blaaier om voort te gaan",
"desktop-auth.login.go-to-browser-login": "Gaan na jou blaaier om aan te meld",
"desktop-auth.login.not-seeing-browser": "Sien jy nie die blaaieroortjie nie?",
"desktop-auth.login.try-again": "Probeer weer",
"desktop-auth.login.new-to-spotify": "Nuut by Spotify?",
"desktop.login.Back": "Terug",
"desktop-auth.login.redirect-to-browser-signup": "Herlei tans na blaaier om registrasie te voltooi",
"desktop-auth.login.redirect-to-browser-login": "Herlei tans na blaaier om aanmelding te voltooi",
"desktop-auth.login.signup-time-out": "Registrasie het uitgetel, probeer asseblief weer",
"desktop-auth.login.login-time-out": "Aanmelding het uitgetel, probeer asseblief weer",
"page.loading": "Laai tans",
"desktop.settings.proxy.title": "Instaanbediener-instellings",
"desktop.settings.proxy.type": "Instaanbedienertipe",
"desktop.settings.proxy.host": "Aanbieder",
"desktop.settings.proxy.port": "Poort",
"desktop.settings.proxy.user": "Gebruikersnaam",
"desktop.settings.proxy.pass": "Wagwoord",
"desktop.login.UnknownLoginErrorMessage": "Diens is tydelik onbeskikbaar, probeer later weer.",
"desktop.login.DefaultErrorMessage": "n Brandmuur is dalk besig om Spotify te blokkeer. Stel asseblief jou brandmuur so dat dit Spotify toelaat. Jy kan ook probeer om die huidige <a href=\"#\" data-action=\"%0%\">instaanbediener-instellings</a> te verander",
"desktop.login.SessionTerminatedMessage": "Jou sessie is beëindig",
"desktop.login.SessionExpiredMessage": "Jou sessie het verval, probeer asseblief weer.",
"desktop.login.BadCredentialsMessage": "Die gebruikersnaam of wagwoord is verkeerd.",
"desktop.login.ErrorResolvingDNS": "Geen internetverbinding bespeur nie.",
"desktop.login.ErrorProxyUnauthorized": "Jou internetnetwerk blokkeer Spotify. Kontak jou netwerkadministrateur om toegang te kry.",
"desktop.login.ErrorProxyForbidden": "Jou internetnetwerk blokkeer Spotify. Kontak jou netwerkadministrateur om toegang te kry.",
"desktop.login.ErrorProxyAuthRequired": "Jou internetnetwerk blokkeer Spotify. Kontak jou netwerkadministrateur of verander jou <a href=\"#\" data-action=\"%0%\">instaanbediener-instellings</a>.",
"desktop.login.CriticalUpdate": "Jou kliënt word opgedateer.",
"desktop.login.UserBannedMessage": "Rekening gedeaktiveer.",
"desktop.login.UserNotAllowedOnPlatformMessage": "Gebruik van hierdie toestel is nie vir jou rekening geaktiveer nie.",
"desktop.login.MissingUserInfoMessage": "Gebruikersprofiel is nie volledig opgedateer nie, <a href=\"%0%\">dateer jou profiel op</a> en meld af en weer aan.",
"desktop.login.RegionMismatchMessage": "Jou land stem nie ooreen met die een wat in jou profiel gestel is nie. Om dit verder te kan gebruik, <a href=\"%0%\">dateer jou profiel op</a> of <a href=\"%1%\">gradeer jou Spotify-rekening op</a>.",
"desktop.login.PremiumUsersOnlyMessage": "Hierdie toep is slegs tot Premium-gebruikers beperk.",
"desktop.login.CreateUserDeniedMessage": "E-pos is reeds aan n ander gebruiker gekoppel.",
"desktop.login.ClientUpdateFail": "Laai asseblief die <a href=\"%0%\">nuutste weergawe</a> van die Spotify-webwerf af.",
"desktop.login.FbUserNotFoundSignUp": "Jy het nie n Spotify-rekening wat met jou Facebook-rekening verbind is nie. As jy n Spotify-rekening het, moet jy asseblief met jou Spotify-gegewens aanmeld. As jy nie n Spotify-rekening het nie, moet jy <a href=\"#\" data-action=\"%0%\">registreer</a>.",
"desktop.login.errorCode": "(Foutkode: {0})",
"desktop.settings.proxy.autodetect": "Outobespeur instellings",
"desktop.settings.proxy.noproxy": "Geen instaanbediener nie",
"desktop.settings.proxy.http": "HTTP",
"desktop.settings.proxy.socks4": "SOCKS4",
"desktop.settings.proxy.socks5": "SOCKS5",
"settings.restartApp": "Begin weer die toep"
}

View File

@ -0,0 +1,53 @@
{
"desktop-auth.login.millions-of-songs": "በሚሊዮን የሚቆጠሩ ሙዚቃዎች።",
"desktop-auth.login.free-on-spotify": "Spotify ላይ በነጻ።",
"desktop-auth.login.collect-and-create": "ይሰብስቡ እና ይፍጠሩ። የእርስዎን ተወዳጅ ሙዚቃ እና ኦዲዮ የግል ቤተ ሙዚቃ ይገንቡ።",
"desktop-auth.login.perfect-work-environment": "ፍጹም የሆነ የሥራ አካባቢን ይፍጠሩ። ምርታማነትዎን በSpotify አጫዋች ዝርዝሮች ያሻሽሉ።",
"desktop.login.PreferencesLink": "ቅንብሮች",
"desktop-auth.login.preview-experience": "ተሞክሮውን አስቀድመው ይመልከቱ",
"desktop-auth.login.sign-up-with-browser": "በነፃ ይመዝገቡ",
"desktop-auth.login.log-in-with-browser": "ግባ",
"close": "ዝጋ",
"desktop-auth.login.go-to-browser-signup": "ለመቀጠል ወደ እርስዎ አሳሽ ይሂዱ",
"desktop-auth.login.go-to-browser-login": "ለመግባት ወደ እርስዎ አሳሽ ይሂዱ",
"desktop-auth.login.not-seeing-browser": "የአሳሽ ትሩ እየታየዎት አይደለም?",
"desktop-auth.login.try-again": "እንደገና ይሞክሩ",
"desktop-auth.login.new-to-spotify": "ለSpotify አዲስ ነዎት?",
"desktop.login.Back": "ተመለስ",
"desktop-auth.login.redirect-to-browser-signup": "ምዝገባን ለማጠናቀቅ ወደ አሳሽ በማዞር ላይ",
"desktop-auth.login.redirect-to-browser-login": "መግባትን ለማጠናቀቅ ወደ አሳሽ በማዞር ላይ",
"desktop-auth.login.signup-time-out": "ምዝገባ ጊዜው አልፎበታል፣ እባክዎ እንደገና ይሞክሩ",
"desktop-auth.login.login-time-out": "መግቢያ ጊዜው አልፎበታል፣ እባክዎ እንደገና ይሞክሩ",
"page.loading": "በመጫን ላይ",
"desktop.settings.proxy.title": "የማፋጠኛ ቅንብሮች",
"desktop.settings.proxy.type": "የማፋጠኛ አይነት",
"desktop.settings.proxy.host": "አስተናጋጅ",
"desktop.settings.proxy.port": "ወደብ",
"desktop.settings.proxy.user": "የተጠቃሚ ስም",
"desktop.settings.proxy.pass": "የይለፍ ቃል",
"desktop.login.UnknownLoginErrorMessage": "አገልግሎት ለጊዜው አይገኝም፣ እባክዎ ቆየት ብለው አንደገና ይሞክሩ።",
"desktop.login.DefaultErrorMessage": "አንድ ኬላ Spotifyን እያገደው ሊሆን ይችላል። እባክዎ ለSpotify ለመፍቀድ የእርስዎን ኬላ ያዘምኑ። በተጨማሪም በአሁኑ ጊዜ ጥቅም ላይ የዋሉትን <a href=\"#\" data-action=\"%0%\">የማፋጠኛ ቅንብሮች</a> ለመቀየር መሞከር ይችላሉ",
"desktop.login.SessionTerminatedMessage": "የእርስዎ ክፍለ ጊዜ ተቋርጧል",
"desktop.login.SessionExpiredMessage": "የእርስዎ ክፍለ ጊዜ ጊዜው አልፎበታል፣ እባክዎ አንደገና ይሞክሩ።",
"desktop.login.BadCredentialsMessage": "የተጠቃሚ ስሙ ወይም የይለፍ ቃሉ የተሳሳተ ነው።",
"desktop.login.ErrorResolvingDNS": "ምንም የበይነመረብ ግንኙነት አልተገኘም።",
"desktop.login.ErrorProxyUnauthorized": "የእርስዎ የበይነመረብ አውታረ መረብ Spotifyን እያገደው ነው። መዳረሻ ለማግኘት የእርስዎን አስተዳዳሪ ያግኙ።",
"desktop.login.ErrorProxyForbidden": "የእርስዎ የበይነመረብ አውታረ መረብ Spotifyን እያገደው ነው። መዳረሻ ለማግኘት የእርስዎን አስተዳዳሪ ያግኙ።",
"desktop.login.ErrorProxyAuthRequired": "የእርስዎ የበይነመረብ አውታረ መረብ Spotifyን እያገደው ነው። የአውታረ መረብ አስተዳዳሪዎን ያግኙ ወይም የእርስዎን <a href=\"#\" data-action=\"%0%\">የማፋጠኛ ቅንብሮች</a> ይቀይሩ።",
"desktop.login.CriticalUpdate": "የእርስዎ ደንበኛ እየተዘመነ ነው።",
"desktop.login.UserBannedMessage": "መለያ ተሰናክሏል።",
"desktop.login.UserNotAllowedOnPlatformMessage": "ይህንን መሣሪያ መጠቀም ለእርስዎ መለያ አልነቃም።",
"desktop.login.MissingUserInfoMessage": "የተጠቃሚ መገለጫ ሙሉ በሙሉ አልዘመነም፣ እባክዎ <a href=\"%0%\"> የእርስዎን መገለጫ ያዘምኑ</a> እና ይውጡ እና እንደገና ይግቡ።",
"desktop.login.RegionMismatchMessage": "የእርስዎ አገር በመገለጫዎ ውስጥ ከተቀናበረው ጋር አይዛመድም። መጠቀም ለመቀጠል፣ <a href=\"%0%\">መገለጫዎን ያዘምኑ</a> ወይም <a href=\"%1%\">የSpotify መለያዎን ያሻሽሉ</a>።",
"desktop.login.PremiumUsersOnlyMessage": "ይህ መተግበሪያ ለPremium ተጠቃሚዎች ብቻ የተገደበ ነው።",
"desktop.login.CreateUserDeniedMessage": "ኢሜይል ቀድሞውኑ ከሌላ ተጠቃሚ ጋር ተገናኝቷል።",
"desktop.login.ClientUpdateFail": "እባክዎ <a href=\"%0%\">የቅርብ ጊዜ ስሪቱ</a>ን ከSpotify ድር ጣቢያ ያውርዱ።",
"desktop.login.FbUserNotFoundSignUp": "ከFacebook መለያዎ ጋር የተገናኘ የ Spotify መለያ የለዎትም። የ Spotify መለያ ካለዎ፣ እባክዎ የSpotify የመግቢያ ማስረጃዎችን በመጠቀም ይግቡ። የ Spotify መለያ ከሌለዎት፣ <a href=\"#\" data-action=\"%0%\">ይመዝገቡ</a>።",
"desktop.login.errorCode": "(የስህተት ኮድ፥ {0})",
"desktop.settings.proxy.autodetect": "ቅንብሮችን በራስ-ሰር አግኝ",
"desktop.settings.proxy.noproxy": "ማፋጠኛ የለም",
"desktop.settings.proxy.http": "ኤችቲቲፒ",
"desktop.settings.proxy.socks4": "SOCKS4",
"desktop.settings.proxy.socks5": "SOCKS5",
"settings.restartApp": "መተግበሪያን እንደገና አስጀምር"
}

View File

@ -0,0 +1,53 @@
{
"desktop-auth.login.millions-of-songs": "ملايين الأغاني.",
"desktop-auth.login.free-on-spotify": "ببلاش على Spotify.",
"desktop-auth.login.collect-and-create": "جمَّع وابني. ابني مكتبتك الموسيقية الشخصية من والموسيقى والمحتوى الصوتي اللي بتحبهم.",
"desktop-auth.login.perfect-work-environment": "اعمل أحلى بيئة عمل، وزوِّد إنتاجيتك مع قوايم أغاني Spotify.",
"desktop.login.PreferencesLink": "الإعدادات",
"desktop-auth.login.preview-experience": "معاينة التجربة",
"desktop-auth.login.sign-up-with-browser": "سجِّل الاشتراك ببلاش",
"desktop-auth.login.log-in-with-browser": "تسجيل الدخول",
"close": "قفل",
"desktop-auth.login.go-to-browser-signup": "Go to your browser to continue",
"desktop-auth.login.go-to-browser-login": "انتقال للمتصفِّح لتسجيل الدخول",
"desktop-auth.login.not-seeing-browser": "مش شايف علامة تبويب المتصفح؟",
"desktop-auth.login.try-again": "حاول مرة تانية",
"desktop-auth.login.new-to-spotify": "إنت مشترك جديد في Spotify؟",
"desktop.login.Back": "رجوع",
"desktop-auth.login.redirect-to-browser-signup": "بنعيد توجيهك دلوقتي للمتصفح علشان تكمِّل تسجيل الاشتراك",
"desktop-auth.login.redirect-to-browser-login": "بنعيد توجيهك للمتصفح علشان تكمِّل تسجيل الدخول",
"desktop-auth.login.signup-time-out": "مهلة تسجيل الاشتراك انتهت، لو سمحت حاول مرة تانية",
"desktop-auth.login.login-time-out": "مهلة تسجيل الدخول انتهت، من فضلك حاوِل مرة تانية",
"page.loading": "بيحمِّل دلوقتي",
"desktop.settings.proxy.title": "إعدادات بروكسي",
"desktop.settings.proxy.type": "نوع بروكسي",
"desktop.settings.proxy.host": "المضيف",
"desktop.settings.proxy.port": "المنفذ",
"desktop.settings.proxy.user": "اسم المستخدم",
"desktop.settings.proxy.pass": "كلمة المرور",
"desktop.login.UnknownLoginErrorMessage": "الخدمة مش متوفرة مؤقتاً، من فضلك حاوِل مرة تانية بعد شوية.",
"desktop.login.DefaultErrorMessage": "ممكن يكون جدار الحماية بيحجب Spotify. لو سمحت اضبط إعدادات جدار الحماية على جهازك علشان يسمح بتشغيل Spotify. وممكن كمان تحاول تغيَّر <a href=\"#\" data-action=\"%0%\">إعدادات بروكسي</a> اللي بتستخدمها دلوقتي",
"desktop.login.SessionTerminatedMessage": "جلستك انتهت",
"desktop.login.SessionExpiredMessage": "انتهت صلاحية الجلسة بتاعتك، لو سمحت حاوِل مرة تانية.",
"desktop.login.BadCredentialsMessage": "اسم المستخدم أو كلمة المرور غلط.",
"desktop.login.ErrorResolvingDNS": "مقدرناش نلاقي اتصال بالنت.",
"desktop.login.ErrorProxyUnauthorized": "شبكة النت بتاعتك مش بتسمح بتشغيل Spotify. اتصل بمسؤول الشبكة علشان تقدر توصل.",
"desktop.login.ErrorProxyForbidden": "شبكة النت بتاعتك مش بتسمح بتشغيل Spotify. اتصل بمسؤول الشبكة علشان تقدر توصل.",
"desktop.login.ErrorProxyAuthRequired": "شبكة النت بتاعتك مش بتسمح بتشغيل Spotify. اتصل بمسؤول الشبكة علشان تقدر توصل، أو غيَّر <a href=\"#\" data-action=\"%0%\">إعدادات بروكسي</a>.",
"desktop.login.CriticalUpdate": "بنحدِّث بيانات العميل بتاعتك دلوقتي.",
"desktop.login.UserBannedMessage": "الحساب مش شغال.",
"desktop.login.UserNotAllowedOnPlatformMessage": "استخدام الجهاز ده مش مسموح بيه لحسابك.",
"desktop.login.MissingUserInfoMessage": "الصفحة الشخصية للمستخدم مش متحدثة بالكامل، من فضلك <a href=\"%0%\">حدِّث صفحتك الشخصية</a> وسجِّل الخروج وبعدها سجِّل الدخول مرة تانية.",
"desktop.login.RegionMismatchMessage": "بلدك مش هي نفس البلد اللي موجودة في صفحتك الشخصية. علشان تكمل استخدام، لازم تعمل <a href=\"%0%\">تحديث لصفحتك الشخصية</a> أو <a href=\"%1%\">ترقية لحسابك على Spotify</a>.",
"desktop.login.PremiumUsersOnlyMessage": "التطبيق ده حصري لمستخدمين اشتراك Premium بس.",
"desktop.login.CreateUserDeniedMessage": "الإيميل مرتبط فعلاً بمستخدم تاني.",
"desktop.login.ClientUpdateFail": "لو سمحت نزِّل <a href=\"%0%\">أحدث إصدار</a> من على موقع Spotify.",
"desktop.login.FbUserNotFoundSignUp": "معندكش حساب Spotify مربوط بحسابك على Facebook. لو عندك حساب على Spotify، من فضلك سجِّل الدخول ببيانات اعتماد حساب Spotify. لو معندكش حساب على Spotify، دوس على <a href=\"#\" data-action=\"%0%\">تسجيل الاشتراك</a>.",
"desktop.login.errorCode": "(رمز المشكلة: {0})",
"desktop.settings.proxy.autodetect": "الكشف التلقائي عن الإعدادات",
"desktop.settings.proxy.noproxy": "مفيش بروكسي",
"desktop.settings.proxy.http": "HTTP",
"desktop.settings.proxy.socks4": "SOCKS4",
"desktop.settings.proxy.socks5": "SOCKS5",
"settings.restartApp": "قفل التطبيق وفتحه تاني"
}

View File

@ -0,0 +1,53 @@
{
"desktop-auth.login.millions-of-songs": "ملايين الأغاني.",
"desktop-auth.login.free-on-spotify": "فابور على Spotify.",
"desktop-auth.login.collect-and-create": "اجمع وصوب. صوب مكتبة ديالك على دوقك اجمع فيها الموسيقى والمقاطع اللي كتبغي.",
"desktop-auth.login.perfect-work-environment": "اخلق أحسن جو اللي يسهّل عليك الخدمة ديالك. زيد في المردود ديالك في الخدمة مع قوائم أغاني Spotify.",
"desktop.login.PreferencesLink": "الإعدادات",
"desktop-auth.login.preview-experience": "التجريب",
"desktop-auth.login.sign-up-with-browser": "صوب حساب فابور",
"desktop-auth.login.log-in-with-browser": "تسجيل الدخول",
"close": "سد",
"desktop-auth.login.go-to-browser-signup": "Go to your browser to continue",
"desktop-auth.login.go-to-browser-login": "سير للمتصفح ديالك باش تدخل",
"desktop-auth.login.not-seeing-browser": "مكتبانش ليك الصفحة في المتصفح؟",
"desktop-auth.login.try-again": "جرب مرة أخرى",
"desktop-auth.login.new-to-spotify": "جديد على Spotify؟",
"desktop.login.Back": "ارجع",
"desktop-auth.login.redirect-to-browser-signup": "جاري الانتقال للمتصفح باش تكمّل التسجيل ديالك",
"desktop-auth.login.redirect-to-browser-login": "جاري الانتقال للمتصفح باش تكمّل الدخول ديالك",
"desktop-auth.login.signup-time-out": "سالات مهلة التسجيل، عفاك حاول مرة أخرى.",
"desktop-auth.login.login-time-out": "سالات مهلة الدخول، عفاك حاول مرة أخرى",
"page.loading": "خدام كيتشارجا",
"desktop.settings.proxy.title": "إعدادات البروكسي",
"desktop.settings.proxy.type": "نوع البروكسي",
"desktop.settings.proxy.host": "المضيف",
"desktop.settings.proxy.port": "المنفذ",
"desktop.settings.proxy.user": "إسم المستخدم",
"desktop.settings.proxy.pass": "كلمة السر",
"desktop.login.UnknownLoginErrorMessage": "هد الخدمة ماكيناش مؤقتا، عفاك جرّب تدخل من بعد.",
"desktop.login.DefaultErrorMessage": "يقدر يكون جدار الحماية هو اللي مبلوكي Spotify. عفاك حدّث جدار الحماية ديالك باش يخدم Spotify. زيد على هادشي، تقدر تحاول تبدّل <a href=\"#\" data-action=\"%0%\">إعدادات البروكسي</a> اللي خدّامة دابا.",
"desktop.login.SessionTerminatedMessage": "سالات الجلسة ديالك",
"desktop.login.SessionExpiredMessage": "مدة صلاحية الجلسة ديالك تسالات. عفاك حاول مرة أخرى.",
"desktop.login.BadCredentialsMessage": "غلط إما في إسم المستخدم أو الكود.",
"desktop.login.ErrorResolvingDNS": "مالقيناش الأنترنت.",
"desktop.login.ErrorProxyUnauthorized": "الأنترنت اللي خدّام بها مبلوكيا Spotify. تواصل مع المسؤول على الأنترنت ديالك باش تقدر تدخل له.",
"desktop.login.ErrorProxyForbidden": "الأنترنت اللي خدّام بها مبلوكيا Spotify. تواصل مع المسؤول على الأنترنت ديالك باش تقدر تدخل له.",
"desktop.login.ErrorProxyAuthRequired": "الأنترنت اللي خدّام بها مبلوكيا Spotify. تواصل مع المسؤول على الأنترنت ديالك أو بدّل <a href=\"#\" data-action=\"%0%\">إعدادات البروكسي</a> اللي داير.",
"desktop.login.CriticalUpdate": "الاكتياليزاسيون ديال العميل ديالك خدامة.",
"desktop.login.UserBannedMessage": "مامفعّلش الحساب.",
"desktop.login.UserNotAllowedOnPlatformMessage": "مامفعّلش الاستعمال ديال هد الجهاز فالحساب ديالك.",
"desktop.login.MissingUserInfoMessage": "الصفحة الشخصية ديال المستخدم باقي مافيهاش المعلومات كلهم، عفاك <a href=\"%0%\">حدّث الصفحة الشخصية ديالك</a> واخرج وعاود ادخل مرة اخرى.",
"desktop.login.RegionMismatchMessage": "الدولة ديالك ماشي هي الدولة اللي داير في صفحتك الشخصية. باش تبقى خدام به، <a href=\"%0%\">حدّث الصفحة الشخصية ديالك</a> أو <a href=\"%1%\">رقي حساب Spotify ديالك</a>.",
"desktop.login.PremiumUsersOnlyMessage": "هد التطبيق خاص بالمستخدمين ديال اشتراك Premium.",
"desktop.login.CreateUserDeniedMessage": "الإيميل مربوط من قبل بواحد الحساب.",
"desktop.login.ClientUpdateFail": "عفاك تليشارجي <a href=\"%0%\">آخر نسخة</a> من الموقع ديال Spotify.",
"desktop.login.FbUserNotFoundSignUp": "ماعندكش حساب Spotify مربوط بحساب Facebook ديالك. إدا عندك حساب Spotify، عفاك دخل بمعطيات Spotify ديالك. <a href=\"#\" data-action=\"%0%\">افتح حساب</a> إدا معندكش حساب Spotify.",
"desktop.login.errorCode": "(رمز الخطأ: {0})",
"desktop.settings.proxy.autodetect": "إعدادات الكشف الأوتوماتيكي",
"desktop.settings.proxy.noproxy": "بلا بروكسي",
"desktop.settings.proxy.http": "HTTP",
"desktop.settings.proxy.socks4": "SOCKS4",
"desktop.settings.proxy.socks5": "SOCKS5",
"settings.restartApp": "اشعل التطبيق من جديد"
}

View File

@ -0,0 +1,53 @@
{
"desktop-auth.login.millions-of-songs": "ملايين الأغاني.",
"desktop-auth.login.free-on-spotify": "مجانًا على Spotify.",
"desktop-auth.login.collect-and-create": "تجميع وإنشاء. زين مكتبتك الشخصية وجمع فيها المحتوى الموسيقي والصوتي اللي تحبه.",
"desktop-auth.login.perfect-work-environment": "زين بيئة عمل مثالية. زوِد إنتاجيتك مع قوائم أغاني Spotify.",
"desktop.login.PreferencesLink": "الإعدادات",
"desktop-auth.login.preview-experience": "معاينة التجربة",
"desktop-auth.login.sign-up-with-browser": "سجل الاشتراك مجانًا",
"desktop-auth.login.log-in-with-browser": "سجّل الدخول",
"close": "قفل",
"desktop-auth.login.go-to-browser-signup": "Go to your browser to continue",
"desktop-auth.login.go-to-browser-login": "الانتقال للمتصفح حقك وتسجيل الدخول",
"desktop-auth.login.not-seeing-browser": "ما تقدر تشوف علامة تبويب المتصفح؟",
"desktop-auth.login.try-again": "حاول مرة ثانية",
"desktop-auth.login.new-to-spotify": "جديد على Spotify؟",
"desktop.login.Back": "الرجوع للخلف",
"desktop-auth.login.redirect-to-browser-signup": "جاري إعادة التوجيه للمتصفِّح لإكمال عملية تسجيل الاشتراك",
"desktop-auth.login.redirect-to-browser-login": "جاري إعادة التوجيه للمتصفِّح لتكميل عملية تسجيل الدخول",
"desktop-auth.login.signup-time-out": "انتهت مهلة تسجيل الاشتراك. من فضلك حاول مرة ثانية.",
"desktop-auth.login.login-time-out": "انتهت مهلة تسجيل الدخول، لو سمحت عيد المحاولة",
"page.loading": "قاعد يحمّل",
"desktop.settings.proxy.title": "إعدادات البروكسي",
"desktop.settings.proxy.type": "نوع البروكسي",
"desktop.settings.proxy.host": "المضيف",
"desktop.settings.proxy.port": "منفذ",
"desktop.settings.proxy.user": "اسم المستخدم",
"desktop.settings.proxy.pass": "كلمة المرور",
"desktop.login.UnknownLoginErrorMessage": "الخدمة مو متاحة مؤقتًا، من فضلك حاول مرة ثانية بعدين.",
"desktop.login.DefaultErrorMessage": "جدار الحماية ممكن يحجب Spotify. لو سمحت حدّث جدار الحماية حقك للسماح لـ Spotify. وتقدرتحاول تغيير <a href=\"#\" data-action=\"%0%\">إعدادات البروكسي</a> المستخدمة حاليًا",
"desktop.login.SessionTerminatedMessage": "تم إنهاء جلستك",
"desktop.login.SessionExpiredMessage": "انتهت جلستك، لو سمحت حاول مرة ثانية.",
"desktop.login.BadCredentialsMessage": "خطأ في اسم المستخدم أو كلمة المرور.",
"desktop.login.ErrorResolvingDNS": "ما في اتصال بالإنترنت.",
"desktop.login.ErrorProxyUnauthorized": "تمنع شبكة الانترنت حقتك Spotify من العمل. اتصل بمسؤول الشبكة علشان يكون عندك حق الوصول.",
"desktop.login.ErrorProxyForbidden": "تمنع شبكة الانترنت حقتك Spotify من العمل. اتصل بمسؤول الشبكة علشان يكون عندك حق الوصول.",
"desktop.login.ErrorProxyAuthRequired": "تمنع شبكة الانترنت حقتك Spotify من العمل. اتصل بمسؤول شبكتك أو غيّر <a href=\"#\" data-action=\"%0%\">إعدادات البروكسي</a> حقتك.",
"desktop.login.CriticalUpdate": "جاري تحديث عميلك.",
"desktop.login.UserBannedMessage": "تم إيقاف الحساب.",
"desktop.login.UserNotAllowedOnPlatformMessage": "ما تقدر تستخدم هذا الجهاز لحسابك.",
"desktop.login.MissingUserInfoMessage": "ما تم تحديث صفحتك الشخصية بالكامل، من فضلك <a href=\"%0%\">حدّث صفحتك الشخصية</a> وسجّل خروج بعدين سجّل دخول مرة ثانية.",
"desktop.login.RegionMismatchMessage": "بلدك مو متطابق مع البلد المحدّد في صفحتك الشخصية. علشان تستمر بالاستخدام <a href=\"%0%\">حدّث صفحتك الشخصية</a> أو <a href=\"%1%\">سوّي ترقية لحساب Spotify حقتك</a>.",
"desktop.login.PremiumUsersOnlyMessage": "هذا التطبيق حصري لمستخدمي Premium بس.",
"desktop.login.CreateUserDeniedMessage": "البريد الإلكتروني مرتبط بمستخدم آخر أصلًا.",
"desktop.login.ClientUpdateFail": "من فضلك نزّل <a href=\"%0%\">أحدث إصدار</a> من موقع Spotify الإلكتروني.",
"desktop.login.FbUserNotFoundSignUp": "مو عندك حساب Spotify متصل بحسابك على Facebook. إذا كان عندك حساب Spotify، لو سمحت سجّل دخول باستخدام بيانات اعتماد Spotify حقتك. إذا ما كان عندك حساب Spotify، من فضلك <a href=\"#\" data-action=\"%0%\">سجّل اشتراك</a>.",
"desktop.login.errorCode": "(رمز الخطأ: {0})",
"desktop.settings.proxy.autodetect": "الاكتشاف التلقائي للإعدادات",
"desktop.settings.proxy.noproxy": "ما في بروكسي",
"desktop.settings.proxy.http": "HTTP",
"desktop.settings.proxy.socks4": "بروتوكول إنترنت SOCKS4",
"desktop.settings.proxy.socks5": "بروتوكول إنترنت SOCKS5",
"settings.restartApp": "إعادة تشغيل التطبيق"
}

View File

@ -0,0 +1,53 @@
{
"desktop-auth.login.millions-of-songs": "ملايين الأغاني",
"desktop-auth.login.free-on-spotify": "مجاناً على Spotify.",
"desktop-auth.login.collect-and-create": "حدد أغانيك المفضَّلة واجمعها في قائمة. أنشئ مكتبة موسيقية شخصية تضم كل الأغاني والمحتوى الصوتي المفضَّل لديك.",
"desktop-auth.login.perfect-work-environment": "أنشئ بيئة العمل المثالية. عزز إنتاجيتك مع قوائم أغاني Spotify.",
"desktop.login.PreferencesLink": "الإعدادات",
"desktop-auth.login.preview-experience": "معاينة التجربة",
"desktop-auth.login.sign-up-with-browser": "تسجيل الاشتراك مجاناً",
"desktop-auth.login.log-in-with-browser": "تسجيل الدخول",
"close": "إغلاق",
"desktop-auth.login.go-to-browser-signup": "انتقِل إلى متصفحك للمتابعة",
"desktop-auth.login.go-to-browser-login": "انتقِل إلى متصفحك لتسجيل الدخول",
"desktop-auth.login.not-seeing-browser": "ألا تظهر علامة تبويب المتصفِّح؟",
"desktop-auth.login.try-again": "أعِد المحاولة",
"desktop-auth.login.new-to-spotify": "هل أنت مستخدم جديد لـ Spotify؟",
"desktop.login.Back": "عودة",
"desktop-auth.login.redirect-to-browser-signup": "جارٍ إعادة التوجيه إلى المتصفِّح لإكمال عملية تسجيل الاشتراك",
"desktop-auth.login.redirect-to-browser-login": "جارٍ إعادة التوجيه إلى المتصفِّح لإكمال عملية تسجيل الدخول",
"desktop-auth.login.signup-time-out": "انتهت مهلة تسجيل الاشتراك. ويُرجى إعادة المحاولة.",
"desktop-auth.login.login-time-out": "انتهت مهلة تسجيل الدخول. يُرجى إعادة المحاولة.",
"page.loading": "جارِ التحميل",
"desktop.settings.proxy.title": "إعدادات البروكسي",
"desktop.settings.proxy.type": "نوع البروكسي",
"desktop.settings.proxy.host": "مضيف",
"desktop.settings.proxy.port": "المنفذ",
"desktop.settings.proxy.user": "اسم المستخدم",
"desktop.settings.proxy.pass": "كلمة المرور",
"desktop.login.UnknownLoginErrorMessage": "الخدمة غير متوفرة مؤقتاً، يرجى المحاولة لاحقاً.",
"desktop.login.DefaultErrorMessage": "قد يكون جدار الحماية يحجب Spotify. يرجى تحديث جدار الحماية الخاص بك للسماح لـ Spotify. بالإضافة إلى ذلك ، يمكنك محاولة تغيير <a href=\"#\" data-action=\"%0%\">إعدادات البروكسي </a>المستخدمة حالياً",
"desktop.login.SessionTerminatedMessage": "انتهت جلستك",
"desktop.login.SessionExpiredMessage": "انتهت صلاحية جلستك، حاول مرة أخرى.",
"desktop.login.BadCredentialsMessage": "خطأ في اسم المستخدم أو كلمة المرور.",
"desktop.login.ErrorResolvingDNS": "لا يبدو أن هناك اتصال بشبكة الإنترنت.",
"desktop.login.ErrorProxyUnauthorized": "شبكة الإنترنت الخاصة بك تعوق تشغيل Spotify اتصل بمسؤول الشبكة للحصول على حق الوصول.",
"desktop.login.ErrorProxyForbidden": "شبكة الإنترنت الخاصة بك تعوق تشغيل Spotify اتصل بمسؤول الشبكة للحصول على حق الوصول.",
"desktop.login.ErrorProxyAuthRequired": "شبكة الإنترنت الخاصة بك تعوق تشغيل Spotify اتصل بمسؤول الشبكة الخاص بك أو قم بتغيير <a href=\"#\" data-action=\"%0%\">إعدادات البروكسي</a>",
"desktop.login.CriticalUpdate": "يتم تحديث عميلك.",
"desktop.login.UserBannedMessage": "الحساب غير مفعّل.",
"desktop.login.UserNotAllowedOnPlatformMessage": "لم يتم تفعيل استخدام هذا الجهاز لحسابك.",
"desktop.login.MissingUserInfoMessage": "لم يتم تحديث صفحة المستخدم الشخصية بالكامل، لذا يرجى <a href=\"%0%\">تحديث صفحتك الشخصية</a> وتسجيل خروجك وإعادة تسجيل الدخول.",
"desktop.login.RegionMismatchMessage": "بلدك لا يتطابق مع البلد المحدّد في صفحتك الشخصية. لمتابعة الاستخدام، <a href=\"%0%\">قم بتحديث صفحتك الشخصية</a> أو <a href=\"%1%\">قم بترقية حسابك على Spotify </a>.",
"desktop.login.PremiumUsersOnlyMessage": "هذا التطبيق حصري لمستخدمي Premium فقط.",
"desktop.login.CreateUserDeniedMessage": "البريد الإلكتروني متصل بالفعل بمستخدم آخر.",
"desktop.login.ClientUpdateFail": "يرجى تنزيل <a href=\"%0%\">أحدث إصدار</a> من موقع Spotify الإلكتروني.",
"desktop.login.FbUserNotFoundSignUp": "ليس لديك حساب Spotify متصل بحسابك على Facebook. إذا كان لديك حساب على Spotify، سجّل الدخول رجاء من خلال بيانات اعتماد Spotify الخاصة بك. إذا لم يكن لديك حساب على Spotify، <a href=\"#\" data-action=\"%0%\">سجّل الاشتراك</a>.",
"desktop.login.errorCode": "(رمز الخطأ: {0})",
"desktop.settings.proxy.autodetect": "الاكتشاف التلقائي للإعدادات",
"desktop.settings.proxy.noproxy": "لا يوجد بروكسي",
"desktop.settings.proxy.http": "HTTP",
"desktop.settings.proxy.socks4": "SOCKS4",
"desktop.settings.proxy.socks5": "SOCKS5",
"settings.restartApp": "أعد تشغيل التطبيق."
}

View File

@ -0,0 +1,53 @@
{
"desktop-auth.login.millions-of-songs": "Milyonlarla mahnı.",
"desktop-auth.login.free-on-spotify": "Spotify-da pulsuzdur.",
"desktop-auth.login.collect-and-create": "Toplayın və yaradın. Sevimli musiqi və audiolarınızın şəxsi kitabxanasını yaradın.",
"desktop-auth.login.perfect-work-environment": "Mükəmməl iş mühiti yaradın. Spotify pleylistləri ilə məhsuldarlığınızı artırın.",
"desktop.login.PreferencesLink": "Parametrlər",
"desktop-auth.login.preview-experience": "Təcrübəni önizləyin",
"desktop-auth.login.sign-up-with-browser": "Pulsuz qeydiyyatdan keç",
"desktop-auth.login.log-in-with-browser": "Giriş et",
"close": "Bağla",
"desktop-auth.login.go-to-browser-signup": "Davam etmək üçün brauzerinizə keçin",
"desktop-auth.login.go-to-browser-login": "Giriş etmək üçün brauzerinizə keçin",
"desktop-auth.login.not-seeing-browser": "Brauzer tabını görmürsünüz?",
"desktop-auth.login.try-again": "Yenidən cəhd et",
"desktop-auth.login.new-to-spotify": "Spotify-da yenisiniz?",
"desktop.login.Back": "Geri",
"desktop-auth.login.redirect-to-browser-signup": "Qeydiyyatı tamamlamaq üçün brauzerə yönləndirilir",
"desktop-auth.login.redirect-to-browser-login": "Girişi tamamlamaq üçün brauzerə yönləndirilir",
"desktop-auth.login.signup-time-out": "Qeydiyyat vaxtı bitdi, yenidən cəhd edin",
"desktop-auth.login.login-time-out": "Giriş vaxtı bitdi, yenidən cəhd edin",
"page.loading": "Yüklənir",
"desktop.settings.proxy.title": "Proksi Parametrləri",
"desktop.settings.proxy.type": "Proksinin növü",
"desktop.settings.proxy.host": "Host",
"desktop.settings.proxy.port": "Port",
"desktop.settings.proxy.user": "İstifadəçi adı",
"desktop.settings.proxy.pass": "Parol",
"desktop.login.UnknownLoginErrorMessage": "Xidmət müvəqqəti olaraq əlçatan deyil, daha sonra yenidən cəhd edin.",
"desktop.login.DefaultErrorMessage": "Qoruyucu divar Spotify-ı bloklamış ola bilər. Spotify-a icazə vermək üçün qoruyucu divarınızı yeniləyin. Bundan əlavə, hazırda istifadə olunan <a href=\"#\" data-action=\"%0%\">proksi parametrlərini</a> dəyişməyə cəhd edə bilərsiniz",
"desktop.login.SessionTerminatedMessage": "Seansınız dayandırıldı",
"desktop.login.SessionExpiredMessage": "Seansınızın vaxtı bitdi, yenidən cəhd edin.",
"desktop.login.BadCredentialsMessage": "İstifadəçi adı və ya parol yanlışdır.",
"desktop.login.ErrorResolvingDNS": "İnternet bağlantısı aşkarlanmadı.",
"desktop.login.ErrorProxyUnauthorized": "İnternet şəbəkəniz Spotify-ı bloklayır. Giriş əldə etmək üçün şəbəkə inzibatçınızla əlaqə saxlayın.",
"desktop.login.ErrorProxyForbidden": "İnternet şəbəkəniz Spotify-ı bloklayır. Giriş əldə etmək üçün şəbəkə inzibatçınızla əlaqə saxlayın.",
"desktop.login.ErrorProxyAuthRequired": "İnternet şəbəkəniz Spotify-ı bloklayır. Şəbəkə inzibatçınızla əlaqə saxlayın və ya <a href=\"#\" data-action=\"%0%\">proksi parametrlərinizi</a> dəyişdirin.",
"desktop.login.CriticalUpdate": "Tətbiqiniz yenilənir.",
"desktop.login.UserBannedMessage": "Hesab deaktiv edildi.",
"desktop.login.UserNotAllowedOnPlatformMessage": "Bu cihazın istifadəsi hesabınız üçün aktiv deyil.",
"desktop.login.MissingUserInfoMessage": "İstifadəçi profili tam yenilənməyib, <a href=\"%0%\">profilinizi yeniləyin və</a> sistemdən çıxıb yenidən daxil olun.",
"desktop.login.RegionMismatchMessage": "Ölkəniz profilinizdəki ilə uyğun gəlmir. İstifadəyə davam etmək üçün <a href=\"%0%\">profilinizi yeniləyin</a> və ya <a href=\"%1%\">Spotify hesabınızı yeniləşdirin</a>.",
"desktop.login.PremiumUsersOnlyMessage": "Bu proqram yalnız Premium istifadəçiləri üçün məhdudlaşdırılıb.",
"desktop.login.CreateUserDeniedMessage": "E-poçt artıq başqa istifadəçiyə qoşulub.",
"desktop.login.ClientUpdateFail": "Spotify veb-saytından ən <a href=\"%0%\">son versiyanı</a> endirin.",
"desktop.login.FbUserNotFoundSignUp": "Facebook hesabınız ilə əlaqələndirilmiş Spotify hesabınız yoxdur. Spotify hesabınız varsa, Spotify məlumatlarınız ilə giriş edin. Spotify hesabınız yoxdursa, <a href=\"#\" data-action=\"%0%\">qeydiyyatdan keçin</a>.",
"desktop.login.errorCode": "(Xəta kodu: {0})",
"desktop.settings.proxy.autodetect": "Parametrlərin avtomatik aşkarlanması",
"desktop.settings.proxy.noproxy": "Proksi yoxdur",
"desktop.settings.proxy.http": "HTTP",
"desktop.settings.proxy.socks4": "SOCKS4",
"desktop.settings.proxy.socks5": "SOCKS5",
"settings.restartApp": "Tətbiqi yenidən başlat"
}

View File

@ -0,0 +1,53 @@
{
"desktop-auth.login.millions-of-songs": "Милиони песни.",
"desktop-auth.login.free-on-spotify": "Безплатно в Spotify.",
"desktop-auth.login.collect-and-create": "Съберете и създайте. Изградете ваша собствена библиотека с любимата си музика и аудиосъдържание.",
"desktop-auth.login.perfect-work-environment": "Създайте идеалната работна среда. Повишете продуктивността със Spotify плейлисти.",
"desktop.login.PreferencesLink": "Настройки",
"desktop-auth.login.preview-experience": "Разгледайте отвътре",
"desktop-auth.login.sign-up-with-browser": "Регистрирайте се безплатно",
"desktop-auth.login.log-in-with-browser": "Влезте в акаунта",
"close": "Затворете",
"desktop-auth.login.go-to-browser-signup": "Отидете в браузъра си, за да продължите",
"desktop-auth.login.go-to-browser-login": "Отидете в браузъра си, за да влезете",
"desktop-auth.login.not-seeing-browser": "Не виждате раздела на браузъра?",
"desktop-auth.login.try-again": "Опитайте отново",
"desktop-auth.login.new-to-spotify": "Нови ли сте в Spotify?",
"desktop.login.Back": "Назад",
"desktop-auth.login.redirect-to-browser-signup": "Пренасочваме ви към браузър, за да завършите регистрацията",
"desktop-auth.login.redirect-to-browser-login": "Пренасочваме ви към браузър, за да завършите влизането",
"desktop-auth.login.signup-time-out": "Времето за регистрация изтече, моля, опитайте отново",
"desktop-auth.login.login-time-out": "Времето за влизане в акаунта изтече, моля, опитайте отново",
"page.loading": "Зареждане",
"desktop.settings.proxy.title": "Настройки на прокси",
"desktop.settings.proxy.type": "Вид прокси",
"desktop.settings.proxy.host": "Хост",
"desktop.settings.proxy.port": "Порт",
"desktop.settings.proxy.user": "Потребителско име",
"desktop.settings.proxy.pass": "Парола",
"desktop.login.UnknownLoginErrorMessage": "Услугата е временно недостъпна. Моля, опитайте отново по‑късно.",
"desktop.login.DefaultErrorMessage": "Възможно е защитна стена да блокира Spotify. Моля, актуализирайте защитната си стена, за да разрешите Spotify. Освен това можете да опитате да промените използваните в момента <a href=\"#\" data-action=\"%0%\">настройки на прокси</a>",
"desktop.login.SessionTerminatedMessage": "Вашата сесия бе прекратена",
"desktop.login.SessionExpiredMessage": "Вашата сесия е изтекла. Моля, опитайте отново.",
"desktop.login.BadCredentialsMessage": "Потребителското име или паролата са неправилни.",
"desktop.login.ErrorResolvingDNS": "Не е установена връзка с интернет.",
"desktop.login.ErrorProxyUnauthorized": "Вашата интернет мрежа блокира Spotify. Свържете се с вашия мрежов администратор, за да получите достъп.",
"desktop.login.ErrorProxyForbidden": "Вашата интернет мрежа блокира Spotify. Свържете се с вашия мрежов администратор, за да получите достъп.",
"desktop.login.ErrorProxyAuthRequired": "Вашата интернет мрежа блокира Spotify. Свържете се с вашия мрежов администратор или променете <a href=\"#\" data-action=\"%0%\">настройките на прокси</a>.",
"desktop.login.CriticalUpdate": "Вашата клиентска версия се актуализира.",
"desktop.login.UserBannedMessage": "Акаунтът е деактивиран.",
"desktop.login.UserNotAllowedOnPlatformMessage": "Използването на това устройство не е активирано за вашия акаунт.",
"desktop.login.MissingUserInfoMessage": "Потребителският профил не е напълно актуализиран. Моля, <a href=\"%0%\">актуализирайте профила си</a>, след това излезте и влезте в акаунта си отново.",
"desktop.login.RegionMismatchMessage": "Вашата държава не съвпада със зададената в профила ви. За да продължите да използвате Spotify, <a href=\"%0%\">актуализирайте профила си</a> или <a href=\"%1%\">надстройте Spotify акаунта си</a>.",
"desktop.login.PremiumUsersOnlyMessage": "Това приложение е ограничено само до Premium потребители.",
"desktop.login.CreateUserDeniedMessage": "Имейлът вече е свързан с друг потребител.",
"desktop.login.ClientUpdateFail": "Моля, изтеглете <a href=\"%0%\">най‑новата версия</a> от уебсайта на Spotify.",
"desktop.login.FbUserNotFoundSignUp": "Нямате Spotify акаунт, свързан с Facebook акаунта си. Ако имате Spotify акаунт, моля, влезте в него с данните си за вход от Spotify. Ако нямате Spotify акаунт, <a href=\"#\" data-action=\"%0%\">се регистрирайте</a>.",
"desktop.login.errorCode": "(Код на грешката: {0})",
"desktop.settings.proxy.autodetect": "Автоматично откриване на настройки",
"desktop.settings.proxy.noproxy": "Няма прокси",
"desktop.settings.proxy.http": "HTTP",
"desktop.settings.proxy.socks4": "SOCKS4",
"desktop.settings.proxy.socks5": "SOCKS5",
"settings.restartApp": "Рестартирайте приложението"
}

View File

@ -0,0 +1,53 @@
{
"desktop-auth.login.millions-of-songs": "लाखों गाने.",
"desktop-auth.login.free-on-spotify": "Spotify पर फ्री बा.",
"desktop-auth.login.collect-and-create": "बटोरीं आ बनाईं. आपन मनपसंद संगीत आ ऑडियो के निजी लाइब्रेरी बनाईं.",
"desktop-auth.login.perfect-work-environment": "खाँटी कामकाजी माहौल बनाईं. Spotify गुलदस्तन से आपन रचनिहारी निखारीं.",
"desktop.login.PreferencesLink": "सेटिंग",
"desktop-auth.login.preview-experience": "अनुभव के जायजा लिहीं",
"desktop-auth.login.sign-up-with-browser": "मुफ्त साइन अप करीं",
"desktop-auth.login.log-in-with-browser": "लॉग इन करीं",
"close": "बंद करीं",
"desktop-auth.login.go-to-browser-signup": "जारी रखे खातिर आपन ब्राउजर में जाईं",
"desktop-auth.login.go-to-browser-login": "लॉग इन करे खातिर आपन ब्राउजर में जाईं",
"desktop-auth.login.not-seeing-browser": "ब्राउजर टैब नइखे लउकत?",
"desktop-auth.login.try-again": "फेर से कोसिस करीं",
"desktop-auth.login.new-to-spotify": "Spotify में नया-नया बानीं का?",
"desktop.login.Back": "पीछे जाईं",
"desktop-auth.login.redirect-to-browser-signup": "साइनअप पूरा करे खातिर ब्राउजर प पठावल जा रहल बा",
"desktop-auth.login.redirect-to-browser-login": "लॉगिन पूरा करे खातिर ब्राउजर प पठावल जा रहल बा",
"desktop-auth.login.signup-time-out": "साइनअप के मोहलत खतम, फेनु कोसिस करीं",
"desktop-auth.login.login-time-out": "लॉगिन के मोहलत खतम, फेनु कोशिश करीं",
"page.loading": "लोडिंग",
"desktop.settings.proxy.title": "प्रॉक्सी सेटिंग",
"desktop.settings.proxy.type": "प्रॉक्सी के प्रकार",
"desktop.settings.proxy.host": "मेजबान",
"desktop.settings.proxy.port": "पोर्ट",
"desktop.settings.proxy.user": "यूजरनाम",
"desktop.settings.proxy.pass": "पासवर्ड",
"desktop.login.UnknownLoginErrorMessage": "सेवा फिलहाल उपलब्ध नइखे, बाद में कोशिश करीं.",
"desktop.login.DefaultErrorMessage": "फायरवॉल भरसक Spotify खातिर अड़ंगा डाल सकेला. फायरवॉल में बदलाव कईके Spotify खातिर गुंजाइश बनाईं. एकरा अलावा रउवा अबहीं चालू <a href=\"#\" data-action=\"%0%\">प्रॉक्सी सेटिंग</a> के बदले के जतन क सकेनीं",
"desktop.login.SessionTerminatedMessage": "राउर सभा बर्खास्त हो चुकल बा",
"desktop.login.SessionExpiredMessage": "राउर सभा के मियाद ओरा गईल, फेर से कोशिश करीं.",
"desktop.login.BadCredentialsMessage": "यूजरनाम चाहे पासवर्ड गलत बा.",
"desktop.login.ErrorResolvingDNS": "इंटरनेट कनेक्शन तनिको नइखे सुगबुगात.",
"desktop.login.ErrorProxyUnauthorized": "राउर इंटरनेट कनेक्शन Spotify खातिर अड़ंगा डालता. पइठे खातिर आपन नेटवर्क प्रबंधक से संपर्क करीं.",
"desktop.login.ErrorProxyForbidden": "राउर इंटरनेट कनेक्शन Spotify खातिर अड़ंगा डालता. पइठे खातिर आपन नेटवर्क प्रबंधक से संपर्क करीं.",
"desktop.login.ErrorProxyAuthRequired": "राउर इंटरनेट कनेक्शन Spotify खातिर अड़ंगा डालता. आपन नेटवर्क प्रबंधक से संपर्क करीं आ नाहीं त आपन <a href=\"#\" data-action=\"%0%\">प्रॉक्सी सेटिंग</a> बदलीं.",
"desktop.login.CriticalUpdate": "राउर गहकी के अपडेट कईल जाता.",
"desktop.login.UserBannedMessage": "अकाउंट निष्क्रिय बा.",
"desktop.login.UserNotAllowedOnPlatformMessage": "राउर अकाउंट खातिर एह डिवाइस के इस्तेमाल सक्रिय नईखे.",
"desktop.login.MissingUserInfoMessage": "गहकी के प्रोफाइल नीक से अपडेट नइखे, पहिले <a href=\"%0%\">आपन प्रोफाइल अपडेट करीं</a>, फेर लॉग आउट करीं अउरी दोबारा लवटीं.",
"desktop.login.RegionMismatchMessage": "राउर देश राउर प्रोफाइल के एगो सेट से मेल नइखे खात. इस्तेमाल जारी रखे खातिर, <a href=\"%0%\">आपन प्रोफाइल अपडेट करीं</a> आ नाहीं त <a href=\"%1%\">आपन Spotify अकाउंट के तरक्की करीं</a>.",
"desktop.login.PremiumUsersOnlyMessage": "ई ऐप खाली प्रीमियम गहकियन ले सीमित बा.",
"desktop.login.CreateUserDeniedMessage": "ईमेल पहिलहीं दोसर गहकी से जुड़ल बा.",
"desktop.login.ClientUpdateFail": "Spotify के वेब साइट से <a href=\"%0%\">नवका वर्जन</a> डाउनलोड करीं.",
"desktop.login.FbUserNotFoundSignUp": "रउवा लगे Facebook अकाउंट से जुड़ल कवनों Spotify अकाउंट नइखे. जे रउवा लगे Spotify अकाउंट बा, त आपन Spotify के जानकारी डाल के लॉग इन करीं. जे रउवा लगे Spotify अकाउंट नइखे, त <a href=\"#\" data-action=\"%0%\">साइन अप</a> करीं.",
"desktop.login.errorCode": "(गड़बड़ी कोड: {0})",
"desktop.settings.proxy.autodetect": "आपरूपी-टोही सेटिंग",
"desktop.settings.proxy.noproxy": "प्रॉक्सी नइखे",
"desktop.settings.proxy.http": "HTTP",
"desktop.settings.proxy.socks4": "SOCKS4",
"desktop.settings.proxy.socks5": "SOCKS5",
"settings.restartApp": "एप के फेर से चालू करीं"
}

View File

@ -0,0 +1,53 @@
{
"desktop-auth.login.millions-of-songs": "লক্ষাধিক গান।",
"desktop-auth.login.free-on-spotify": "লক্ষাধিক গানের সমাহার।",
"desktop-auth.login.collect-and-create": "সংগ্রহ করুন এবং তৈরি করুন। আপনার পছন্দসই মিউজিক এবং অডিওর নিজস্ব লাইব্রেরি তৈরি করুন।",
"desktop-auth.login.perfect-work-environment": "কাজের উপযুক্ত পরিবেশ তৈরি করুন। Spotify প্লেলিস্টের সাহায্যে আপনার প্রোডাক্টিভিটি বাড়ান।",
"desktop.login.PreferencesLink": "সেটিংস",
"desktop-auth.login.preview-experience": "এই অভিজ্ঞতার প্রিভিউ দেখুন",
"desktop-auth.login.sign-up-with-browser": "ফ্রিতে সাইন আপ করুন",
"desktop-auth.login.log-in-with-browser": "লগ ইন করুন",
"close": "বন্ধ করুন",
"desktop-auth.login.go-to-browser-signup": "চালিয়ে যেতে আপনার ব্রাউজারে যান",
"desktop-auth.login.go-to-browser-login": "লগ ইন করতে আপনার ব্রাউজারে যান",
"desktop-auth.login.not-seeing-browser": "ব্রাউজার ট্যাব দেখতে পাচ্ছেন না?",
"desktop-auth.login.try-again": "আবার চেষ্টা করুন",
"desktop-auth.login.new-to-spotify": "Spotify-তে নতুন?",
"desktop.login.Back": "পিছনে যান",
"desktop-auth.login.redirect-to-browser-signup": "সাইনআপ সম্পূর্ণ করতে ব্রাউজারে রিডাইরেক্ট করা হচ্ছে",
"desktop-auth.login.redirect-to-browser-login": "লগইন সম্পূর্ণ করতে ব্রাউজারে রিডাইরেক্ট করা হচ্ছে",
"desktop-auth.login.signup-time-out": "সাইনআপ করার সময় শেষ হয়ে গেছে, অনুগ্রহ করে আবার চেষ্টা করুন",
"desktop-auth.login.login-time-out": "লগইন করার সময় শেষ হয়ে গেছে, অনুগ্রহ করে আবার চেষ্টা করুন",
"page.loading": "লোড হচ্ছে",
"desktop.settings.proxy.title": "প্রক্সি সেটিংস",
"desktop.settings.proxy.type": "প্রক্সির ধরন",
"desktop.settings.proxy.host": "হোস্ট",
"desktop.settings.proxy.port": "পোর্ট করুন",
"desktop.settings.proxy.user": "ব্যবহারকারীর নাম",
"desktop.settings.proxy.pass": "পাসওয়ার্ড",
"desktop.login.UnknownLoginErrorMessage": "পরিষেবা সাময়িকভাবে অনুপলভ্য, অনুগ্রহ করে একটু পরে আবার চেষ্টা করুন।",
"desktop.login.DefaultErrorMessage": "একটি ফায়ারওয়াল হয়তো Spotify-কে ব্লক করছে। Spotify-কে অনুমতি দিতে আপনার ফায়ারওয়াল আপডেট করুন। এছাড়া, আপনি বর্তমানে ব্যবহার হওয়া <a href=\"#\" data-action=\"%0%\">প্রক্সি সেটিংস</a> পরিবর্তন করার চেষ্টা করতে পারেন",
"desktop.login.SessionTerminatedMessage": "আপনার সেশনটি বন্ধ করা হয়েছে",
"desktop.login.SessionExpiredMessage": "আপনার সেশনের মেয়াদ শেষ হয়ে গেছে, অনুগ্রহ করে আবার চেষ্টা করুন।",
"desktop.login.BadCredentialsMessage": "ব্যবহারকারীর নাম বা পাসওয়ার্ড ভুল।",
"desktop.login.ErrorResolvingDNS": "কোনো ইন্টারনেট কানেকশন শনাক্ত করা যায়নি।",
"desktop.login.ErrorProxyUnauthorized": "আপনার ইন্টারনেট নেটওয়ার্ক Spotify-কে ব্লক করছে। অ্যাক্সেস পেতে আপনার নেটওয়ার্ক অ্যাডমিনিস্ট্রেটরের সাথে যোগাযোগ করুন।",
"desktop.login.ErrorProxyForbidden": "আপনার ইন্টারনেট নেটওয়ার্ক Spotify-কে ব্লক করছে। অ্যাক্সেস পেতে আপনার নেটওয়ার্ক অ্যাডমিনিস্ট্রেটরের সাথে যোগাযোগ করুন।",
"desktop.login.ErrorProxyAuthRequired": "আপনার ইন্টারনেট নেটওয়ার্ক Spotify-কে ব্লক করছে। আপনার নেটওয়ার্ক অ্যাডমিনিস্ট্রেটরের সাথে যোগাযোগ করুন বা আপনার <a href=\"#\" data-action=\"%0%\">প্রক্সি সেটিংস</a> পরিবর্তন করুন।",
"desktop.login.CriticalUpdate": "আপনার ক্লায়েন্ট আপডেট করা হচ্ছে।",
"desktop.login.UserBannedMessage": "অ্যাকাউন্ট নিষ্ক্রিয় করা হয়েছে।",
"desktop.login.UserNotAllowedOnPlatformMessage": "আপনার অ্যাকাউন্টের জন্য এই ডিভাইসের ব্যবহারের সুবিধা চালু করা নেই।",
"desktop.login.MissingUserInfoMessage": "ব্যবহারকারীর প্রোফাইল সম্পূর্ণরূপে আপডেট করা নেই, অনুগ্রহ করে <a href=\"%0%\">আপনার প্রোফাইল আপডেট করুন</a> এবং লগ আউট করে আবার লগ ইন করুন।",
"desktop.login.RegionMismatchMessage": "আপনার দেশ, আপনার প্রোফাইলে সেট করা দেশের সাথে মিলছে না। ব্যবহার করা চালিয়ে যেতে, <a href=\"%0%\">আপনার প্রোফাইল আপডেট করুন</a> বা <a href=\"%1%\">আপনার Spotify অ্যাকাউন্ট আপগ্রেড করুন</a>।",
"desktop.login.PremiumUsersOnlyMessage": "এই অ্যাপটি কেবল Premium ব্যবহারকারীদের জন্য সীমাবদ্ধ করা রয়েছে।",
"desktop.login.CreateUserDeniedMessage": "এই ইমেলটি আগে থেকেই আরেকজন ব্যবহারকারীর সাথে যুক্ত আছে।",
"desktop.login.ClientUpdateFail": "অনুগ্রহ করে Spotify ওয়েবসাইট থেকে <a href=\"%0%\">সর্বশেষ ভার্সন</a>টি ডাউনলোড করুন।",
"desktop.login.FbUserNotFoundSignUp": "আপনার Facebook অ্যাকাউন্টের সাথে কোনও Spotify অ্যাকাউন্ট কানেক্ট করা নেই। আপনার Spotify অ্যাকাউন্ট থাকলে, অনুগ্রহ করে আপনার Spotify ক্রেডেনশিয়াল দিয়ে লগ ইন করুন। আপনার যদি কোনও Spotify অ্যাকাউন্ট না থাকে তবে <a href=\"#\" data-action=\"%0%\">সাইন আপ করুন</a>।",
"desktop.login.errorCode": "(সমস্যার কোড: {0})",
"desktop.settings.proxy.autodetect": "সেটিংস অটো-ডিটেক্ট করুন",
"desktop.settings.proxy.noproxy": "কোনও প্রক্সি নেই",
"desktop.settings.proxy.http": "HTTP",
"desktop.settings.proxy.socks4": "SOCKS4",
"desktop.settings.proxy.socks5": "SOCKS5",
"settings.restartApp": "অ্যাপ আবার চালু করুন।"
}

View File

@ -0,0 +1,53 @@
{
"desktop-auth.login.millions-of-songs": "Milioni pjesama.",
"desktop-auth.login.free-on-spotify": "Besplatno na Spotifyu.",
"desktop-auth.login.collect-and-create": "Prikupljajte i kreirajte. Izgradite ličnu biblioteku svoje omiljene muzike i zvučnih sadržaja.",
"desktop-auth.login.perfect-work-environment": "Kreirajte savršeno radno okruženje. Poboljšajte produktivnost uz plejliste na Spotifyu.",
"desktop.login.PreferencesLink": "Postavke",
"desktop-auth.login.preview-experience": "Pregledajte iskustvo",
"desktop-auth.login.sign-up-with-browser": "Besplatno se registrirajte",
"desktop-auth.login.log-in-with-browser": "Prijava",
"close": "Zatvori",
"desktop-auth.login.go-to-browser-signup": "Go to your browser to continue",
"desktop-auth.login.go-to-browser-login": "Idite u preglednik da se prijavite",
"desktop-auth.login.not-seeing-browser": "Ne vidite karticu preglednika?",
"desktop-auth.login.try-again": "Pokušajte ponovo",
"desktop-auth.login.new-to-spotify": "Novi ste na Spotifyu?",
"desktop.login.Back": "Nazad",
"desktop-auth.login.redirect-to-browser-signup": "Preusmjeravanje u preglednik radi dovršavanja registracije",
"desktop-auth.login.redirect-to-browser-login": "Preusmjeravanje u preglednik radi dovršavanja prijave",
"desktop-auth.login.signup-time-out": "Isteklo je vrijeme za registraciju. Pokušajte ponovo.",
"desktop-auth.login.login-time-out": "Isteklo je vrijeme za prijavu. Pokušajte ponovo.",
"page.loading": "Učitavanje",
"desktop.settings.proxy.title": "Postavke proksija",
"desktop.settings.proxy.type": "Vrsta proksija",
"desktop.settings.proxy.host": "Organizator",
"desktop.settings.proxy.port": "Priključak",
"desktop.settings.proxy.user": "Korisničko ime",
"desktop.settings.proxy.pass": "Lozinka",
"desktop.login.UnknownLoginErrorMessage": "Usluga trenutno nije dostupna. Pokušajte ponovo kasnije.",
"desktop.login.DefaultErrorMessage": "Zaštitni zid možda blokira Spotify. Ažurirajte zaštitni zid da omogućite Spotify. Pored toga, možete pokušati promjeniti trenutno korištene <a href=\"#\" data-action=\"%0%\">postavke proksija</a>",
"desktop.login.SessionTerminatedMessage": "Sesija je prekinuta",
"desktop.login.SessionExpiredMessage": "Sesija je istekla. Pokušajte ponovo.",
"desktop.login.BadCredentialsMessage": "Korisničko ime ili lozinka nisu tačni.",
"desktop.login.ErrorResolvingDNS": "Nije otkrivena internetska veza.",
"desktop.login.ErrorProxyUnauthorized": "Internetska mreža blokira Spotify. Obratite se administratoru mreže da dobijete pristup.",
"desktop.login.ErrorProxyForbidden": "Internetska mreža blokira Spotify. Obratite se administratoru mreže da dobijete pristup.",
"desktop.login.ErrorProxyAuthRequired": "Internetska mreža blokira Spotify. Obratite se administratoru mreže ili promijenite <a href=\"#\" data-action=\"%0%\">postavke proksija</a>.",
"desktop.login.CriticalUpdate": "Klijent se ažurira.",
"desktop.login.UserBannedMessage": "Račun je onemogućen.",
"desktop.login.UserNotAllowedOnPlatformMessage": "Korištenje ovog uređaja nije omogućeno za vaš račun.",
"desktop.login.MissingUserInfoMessage": "Korisnički profil nije u potpunosti ažuriran. <a href=\"%0%\">Ažurirajte profil</a>, a zatim se odjavite i ponovo prijavite.",
"desktop.login.RegionMismatchMessage": "Zemlja se ne podudara sa zemljom postavljenom na profilu. Da nastavite koristiti, <a href=\"%0%\">ažurirajte profil</a> ili <a href=\"%1%\">nadogradite Spotify račun</a>.",
"desktop.login.PremiumUsersOnlyMessage": "Aplikacija je ograničena samo za korisnike Premiuma.",
"desktop.login.CreateUserDeniedMessage": "Adresa e-pošte je već povezana s drugim korisnikom.",
"desktop.login.ClientUpdateFail": "Preuzmite <a href=\"%0%\">najnoviju verziju</a> s web lokacije Spotify.",
"desktop.login.FbUserNotFoundSignUp": "Nemate Spotify račun povezan s Facebook računom. Ako imate Spotify račun, prijavite se s akreditivima za Spotify. Ako nemate Spotify račun, <a href=\"#\" data-action=\"%0%\">registrirajte se</a>.",
"desktop.login.errorCode": "(Kôd greške: {0})",
"desktop.settings.proxy.autodetect": "Postavke automatskog otkrivanja",
"desktop.settings.proxy.noproxy": "Nema proksija",
"desktop.settings.proxy.http": "HTTP",
"desktop.settings.proxy.socks4": "SOCKS4",
"desktop.settings.proxy.socks5": "SOCKS5",
"settings.restartApp": "Ponovo pokreni aplikaciju"
}

View File

@ -0,0 +1,53 @@
{
"desktop-auth.login.millions-of-songs": "Milions de cançons",
"desktop-auth.login.free-on-spotify": "de franc a Spotify.",
"desktop-auth.login.collect-and-create": "Col·lecciona i crea. Crea una biblioteca personal amb la teva música i àudio preferits.",
"desktop-auth.login.perfect-work-environment": "Crea l'entorn de treball perfecte. Millora la teva productivitat amb les llistes de Spotify.",
"desktop.login.PreferencesLink": "Configuració",
"desktop-auth.login.preview-experience": "Prova l'experiència",
"desktop-auth.login.sign-up-with-browser": "Registra't gratis",
"desktop-auth.login.log-in-with-browser": "Inicia la sessió",
"close": "Tanca",
"desktop-auth.login.go-to-browser-signup": "Go to your browser to continue",
"desktop-auth.login.go-to-browser-login": "Ves al navegador per iniciar la sessió",
"desktop-auth.login.not-seeing-browser": "No veus la pestanya del navegador?",
"desktop-auth.login.try-again": "Torna-ho a provar",
"desktop-auth.login.new-to-spotify": "És el primer cop que fas servir Spotify?",
"desktop.login.Back": "Enrere",
"desktop-auth.login.redirect-to-browser-signup": "S'està redirigint al navegador per completar el registre",
"desktop-auth.login.redirect-to-browser-login": "S'està redirigint al navegador per completar l'inici de sessió",
"desktop-auth.login.signup-time-out": "S'ha esgotat el temps del procés de registre. Torna-ho a provar.",
"desktop-auth.login.login-time-out": "S'ha esgotat el temps d'inici de sessió. Torna-ho a provar",
"page.loading": "S'està carregant",
"desktop.settings.proxy.title": "Configuració del servidor intermediari",
"desktop.settings.proxy.type": "Tipus de servidor intermediari",
"desktop.settings.proxy.host": "Amfitrió",
"desktop.settings.proxy.port": "Port",
"desktop.settings.proxy.user": "Nom d'usuari",
"desktop.settings.proxy.pass": "Contrasenya",
"desktop.login.UnknownLoginErrorMessage": "El servei no està disponible temporalment. Torna-ho a provar més tard.",
"desktop.login.DefaultErrorMessage": "És possible que un tallafoc estigui bloquejant Spotify. Modifica el tallafoc per permetre Spotify. També pots provar de canviar la <a href=\"#\" data-action=\"%0%\">configuració del servidor intermediari</a> actual.",
"desktop.login.SessionTerminatedMessage": "S'ha tancat la sessió",
"desktop.login.SessionExpiredMessage": "La sessió ha caducat; torna-ho a provar.",
"desktop.login.BadCredentialsMessage": "El nom d'usuari o la contrasenya no són correctes.",
"desktop.login.ErrorResolvingDNS": "No s'ha detectat cap connexió a Internet.",
"desktop.login.ErrorProxyUnauthorized": "La teva connexió a Internet està bloquejant Spotify. Posa't en contacte amb l'administrador de la xarxa per poder-hi accedir.",
"desktop.login.ErrorProxyForbidden": "La teva connexió a Internet està bloquejant Spotify. Posa't en contacte amb l'administrador de la xarxa per poder-hi accedir.",
"desktop.login.ErrorProxyAuthRequired": "La teva connexió a Internet està bloquejant Spotify. Posa't en contacte amb l'administrador de la xarxa o canvia la <a href=\"#\" data-action=\"%0%\">configuració del servidor intermediari</a>.",
"desktop.login.CriticalUpdate": "S'està actualitzant el teu client.",
"desktop.login.UserBannedMessage": "Compte desactivat.",
"desktop.login.UserNotAllowedOnPlatformMessage": "El teu compte no té activat l'ús d'aquest dispositiu.",
"desktop.login.MissingUserInfoMessage": "El perfil d'usuari no està complet; si us plau, <a href=\"%0%\">actualitza el teu perfil</a>, tanca la sessió i torna-la a iniciar.",
"desktop.login.RegionMismatchMessage": "El teu país no coincideix amb el que hi ha al teu perfil. Per continuar utilitzant Spotify, <a href=\"%0%\">actualitza el teu perfil</a> o <a href=\"%1%\">millora el teu pla de Spotify</a>.",
"desktop.login.PremiumUsersOnlyMessage": "Aquesta aplicació està restringida només als usuaris Premium.",
"desktop.login.CreateUserDeniedMessage": "Aquesta adreça electrònica ja està vinculada a un altre usuari.",
"desktop.login.ClientUpdateFail": "Descarrega l'<a href=\"%0%\">última versió</a> des del lloc web de Spotify.",
"desktop.login.FbUserNotFoundSignUp": "No tens cap compte de Spotify connectat al compte de Facebook. Si tens un compte de Spotify, inicia la sessió amb l'adreça electrònica o el nom d'usuari que fas servir per a Spotify. Si no tens cap compte de Spotify, <a href=\"#\" data-action=\"%0%\">registra't</a>.",
"desktop.login.errorCode": "(Codi d'error: {0})",
"desktop.settings.proxy.autodetect": "Configuració de detecció automàtica",
"desktop.settings.proxy.noproxy": "Sense servidor intermediari",
"desktop.settings.proxy.http": "HTTP",
"desktop.settings.proxy.socks4": "SOCKS4",
"desktop.settings.proxy.socks5": "SOCKS5",
"settings.restartApp": "Reinicia l'aplicació"
}

View File

@ -0,0 +1,53 @@
{
"desktop-auth.login.millions-of-songs": "Miliony skladeb.",
"desktop-auth.login.free-on-spotify": "Zdarma na Spotify.",
"desktop-auth.login.collect-and-create": "Sbírej a tvoř. Vybuduj si osobní knihovnu svojí oblíbené hudby a zvuku.",
"desktop-auth.login.perfect-work-environment": "Vytvoř si dokonalé pracovní prostředí. Zvyš svoji produktivitu s playlisty Spotify.",
"desktop.login.PreferencesLink": "Nastavení",
"desktop-auth.login.preview-experience": "Zobrazit náhled prostředí",
"desktop-auth.login.sign-up-with-browser": "Registrovat se zdarma",
"desktop-auth.login.log-in-with-browser": "Přihlásit se",
"close": "Zavřít",
"desktop-auth.login.go-to-browser-signup": "Jestli chceš pokračovat, přejdi do prohlížeče",
"desktop-auth.login.go-to-browser-login": "Jestli se chceš přihlásit, přejdi do prohlížeče",
"desktop-auth.login.not-seeing-browser": "Nevidíš záložku prohlížeče?",
"desktop-auth.login.try-again": "Zkusit znovu",
"desktop-auth.login.new-to-spotify": "Jsi novým uživatelem Spotify?",
"desktop.login.Back": "Zpět",
"desktop-auth.login.redirect-to-browser-signup": "Přesměrování do prohlížeče pro dokončení registrace",
"desktop-auth.login.redirect-to-browser-login": "Přesměrování do prohlížeče pro dokončení přihlášení",
"desktop-auth.login.signup-time-out": "Časový limit pro registraci vypršel, zkus to znovu",
"desktop-auth.login.login-time-out": "Časový limit pro přihlášení vypršel, zkus to znovu",
"page.loading": "Načítání",
"desktop.settings.proxy.title": "Nastavení proxy serveru",
"desktop.settings.proxy.type": "Typ proxy serveru",
"desktop.settings.proxy.host": "Hostitel",
"desktop.settings.proxy.port": "Port",
"desktop.settings.proxy.user": "Uživatelské jméno",
"desktop.settings.proxy.pass": "Heslo",
"desktop.login.UnknownLoginErrorMessage": "Služba je dočasně nedostupná, zkus to prosím znovu později.",
"desktop.login.DefaultErrorMessage": "Je možné, že aplikaci Spotify blokuje brána firewall. Aktualizuj prosím bránu firewall tak, aby Spotify povolila. Případně můžeš zkusit změnit právě používaná <a href=\"#\" data-action=\"%0%\">nastavení proxy serveru</a>",
"desktop.login.SessionTerminatedMessage": "Tvoje relace byla ukončena",
"desktop.login.SessionExpiredMessage": "Platnost relace vypršela. Zkus to prosím znovu.",
"desktop.login.BadCredentialsMessage": "Uživatelské jméno nebo heslo není správné.",
"desktop.login.ErrorResolvingDNS": "Nebylo rozpoznáno připojení k internetu.",
"desktop.login.ErrorProxyUnauthorized": "Tvoje síť Spotify blokuje. Jestli se chceš přihlásit, požádej o pomoc správce sítě.",
"desktop.login.ErrorProxyForbidden": "Tvoje síť Spotify blokuje. Jestli se chceš přihlásit, požádej o pomoc správce sítě.",
"desktop.login.ErrorProxyAuthRequired": "Tvoje síť Spotify blokuje. Požádej o pomoc správce sítě nebo změň <a href=\"#\" data-action=\"%0%\">nastavení proxy serveru</a>.",
"desktop.login.CriticalUpdate": "Probíhá aktualizace tvého klienta.",
"desktop.login.UserBannedMessage": "Účet zablokován.",
"desktop.login.UserNotAllowedOnPlatformMessage": "Použití tohoto zařízení není pro tvůj účet povoleno.",
"desktop.login.MissingUserInfoMessage": "Profil uživatele nebyl plně aktualizován, <a href=\"%0%\">aktualizuj prosím svůj profil,</a> odhlas se a potom se znovu přihlas.",
"desktop.login.RegionMismatchMessage": "Tvá země neodpovídá zemi, která je nastavena v tvém profilu. Chceš-li službu nadále používat, <a href=\"%0%\">aktualizuj svůj profil</a> nebo <a href=\"%1%\">upgraduj svůj účet Spotify</a>.",
"desktop.login.PremiumUsersOnlyMessage": "Tato aplikace je omezena pouze na uživatele služby Premium.",
"desktop.login.CreateUserDeniedMessage": "E-mail je již připojen k jinému uživateli.",
"desktop.login.ClientUpdateFail": "Stáhni si prosím <a href=\"%0%\">nejnovější verzi</a> z webových stránek Spotify.",
"desktop.login.FbUserNotFoundSignUp": "Nemáš účet Spotify propojený s facebookovým účtem. Pokud máš účet Spotify, přihlas se pomocí přihlašovacích údajů pro Spotify. Jestli účet Spotify ještě nemáš, <a href=\"#\" data-action=\"%0%\">zaregistruj se</a>.",
"desktop.login.errorCode": "(Chybový kód: {0})",
"desktop.settings.proxy.autodetect": "Nastavení automatické detekce",
"desktop.settings.proxy.noproxy": "Bez proxy serveru",
"desktop.settings.proxy.http": "HTTP",
"desktop.settings.proxy.socks4": "SOCKS4",
"desktop.settings.proxy.socks5": "SOCKS5",
"settings.restartApp": "Restartovat aplikaci"
}

Some files were not shown because too many files have changed in this diff Show More