Last active
March 26, 2021 11:33
-
-
Save Ratsuky/3f98694ed9baab5f707cd57003c72519 to your computer and use it in GitHub Desktop.
Simple script to add key-bindings on spotify
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // ==UserScript== | |
| // @name Spotify Keybinding | |
| // @namespace http://tampermonkey.net/ | |
| // @version 0.1 | |
| // @description try to take over the world! | |
| // @author You | |
| // @match https://open.spotify.com/* | |
| // @grant none | |
| // @require http://code.jquery.com/jquery-3.4.1.min.js | |
| // ==/UserScript== | |
| /* | |
| ||============================================|| | |
| ||integrates changes to match ui modifications|| | |
| ||============================================|| | |
| adjusts height of playlist to match the height | |
| increase introduced be the acompaniing stylus style | |
| ||============================================|| | |
| || Adds ability to use keybindings || | |
| ||============================================|| | |
| [control] + [alt] + [f] | |
| -- like the currently playing song | |
| ||============================================|| | |
| [control] + [alt] + [d] | |
| -- toggle repeat | |
| ||============================================|| | |
| [control] + [alt] + [w] - Previous | |
| [control] + [alt] + [s] - Next | |
| -- vertically placed keys for the prev/next bindings | |
| ||============================================|| | |
| [control] + [alt] + [q] - Go to current playlist | |
| ||============================================|| | |
| ||============================================|| | |
| || WIP features || | |
| ||============================================|| | |
| [control] + [alt] + [a] - scroll current song into view | |
| // [ control ] + [ alt ] + [ home ] -- set player to start of song | |
| */ | |
| (function () { | |
| 'use strict'; | |
| let nowPlayingClassName = 'now-playing-tracklist-row' | |
| let playlistRows = $('div[data-testid="tracklist-row"]'); | |
| let buffer = []; | |
| let bindings = [ | |
| {binding: ["control", "alt", "q"], action: kbd_viewCrtPlaylist}, | |
| {binding: ["control", "alt", "a"], action: kbd_viewCrtPlaying}, | |
| {binding: ["control", "alt", "f"], action: kbd_likeCrtPlaying}, | |
| {binding: ["control", "alt", "d"], action: kbd_repeatToggle}, | |
| {binding: ["control", "alt", "w"], action: kbd_previousSong}, | |
| {binding: ["control", "alt", "s"], action: kbd_nextSong}, | |
| {binding: ["control", "alt", "home"], action: kbd_startOfSong}, | |
| ]; | |
| Array.prototype.last = function () { | |
| return this[this.length - 1]; | |
| } | |
| function arraysMatch(arr1, arr2) { | |
| if (arr1.length !== arr2.length) { | |
| return false; | |
| } | |
| for (let i = 0; i < arr1.length; i++) { | |
| if (arr1[i] !== arr2[i]) return false; | |
| } | |
| return true; | |
| } | |
| function enforceAdjustedPlaylistHeight() { | |
| let contentBoxes = $('.contentSpacing > div[role="grid"]'); | |
| $.each(contentBoxes, function (k, contentBox) { | |
| let tracklistRows = $(contentBox).find('[data-testid="tracklist-row"]'); | |
| let rowsCount = tracklistRows.length; | |
| let tracklistRowsBox = $(tracklistRows[0]).parent().parent().parent(); | |
| let hasCurrentlyPLaying = tracklistRowsBox.find('.' + nowPlayingClassName); | |
| let rowHeight = 65; | |
| let playingRowHeight = 85; | |
| let finalHeight = rowHeight * rowsCount; | |
| if (hasCurrentlyPLaying) { | |
| finalHeight = (rowHeight * (rowsCount - 1)) + playingRowHeight; | |
| } | |
| tracklistRowsBox.css('height', finalHeight); | |
| }); | |
| } | |
| function highlightCurrentlyPLaying() { | |
| playlistRows = $('div[data-testid="tracklist-row"]'); | |
| playlistRows.each(function (k, v) { | |
| let hasPauseBtn = $(v).find('button[aria-label="Pause"]'); | |
| if (hasPauseBtn.length === 1) { | |
| $(v).addClass(nowPlayingClassName) | |
| } else { | |
| if ($(v).hasClass(nowPlayingClassName)) { | |
| $(v).removeClass(nowPlayingClassName); | |
| } | |
| } | |
| }); | |
| } | |
| function __triggerPlayBtn() { | |
| $('.Root__now-playing-bar button[data-testid="control-button-play"]').trigger('click'); | |
| } | |
| function __jumpToPlaylist() { | |
| $('.Root__now-playing-bar img[data-testid="cover-art-image"]').trigger('click'); | |
| } | |
| function __changeSong(direction) { | |
| playlistRows = $('div[data-testid="tracklist-row"]'); | |
| playlistRows.each(function (k, v) { | |
| let hasPauseBtn = $(v).find('button[aria-label="Pause"]'); | |
| if (hasPauseBtn.length == 1) { | |
| let index = k; | |
| if (direction == 'prev') { | |
| index -= 1; | |
| } else if (direction == 'next') { | |
| index += 1; | |
| } | |
| $(playlistRows[index]).find('button[aria-label^="Play"]').trigger('click'); | |
| } | |
| }).bind(direction); | |
| highlightCurrentlyPLaying(); | |
| } | |
| function kbd_nextSong() { | |
| __jumpToPlaylist(); | |
| __triggerPlayBtn(); | |
| setTimeout(function () {__changeSong('next');}, 2000); | |
| } | |
| function kbd_previousSong() { | |
| __jumpToPlaylist(); | |
| __triggerPlayBtn(); | |
| setTimeout(function () {__changeSong('prev');}, 2000); | |
| } | |
| function kbd_viewCrtPlaylist() { | |
| __jumpToPlaylist(); | |
| } | |
| async function kbd_viewCrtPlaying() { | |
| await __jumpToPlaylist(); | |
| window.addEventListener() | |
| playlistRows = $('div[data-testid="tracklist-row"]'); | |
| var currentlyPlayingKey = 0; | |
| var offset = {}; | |
| playlistRows.each(function (k, v) { | |
| var hasPauseBtn = $(v).find('button[aria-label="Pause"]'); | |
| if (hasPauseBtn.length == 1) { | |
| currentlyPlayingKey = k; | |
| } | |
| }); | |
| // console.log('currentlyPlayingKey', currentlyPlayingKey); | |
| offset = $(playlistRows[currentlyPlayingKey]).offset(); | |
| // console.log(offset); | |
| $('html, body').animate({scrollTop: offset.top, scrollLeft: offset.left}); | |
| } | |
| function kbd_likeCrtPlaying() { | |
| $('.Root__now-playing-bar').find('.control-button.control-button-heart > button').trigger('click'); | |
| } | |
| function kbd_repeatToggle() { | |
| let repeatListBtn = $('.Root__now-playing-bar button[data-testid="control-button-repeat"]'); | |
| if (repeatListBtn.length > 0) { | |
| repeatListBtn.trigger('click'); | |
| return; | |
| } | |
| } | |
| // attempt to go to start of song | |
| function kbd_startOfSong() { | |
| var progressBarBg = $('.Root__now-playing-bar .playback-bar .progress-bar__bg'); | |
| var progressBarBtn = $('.Root__now-playing-bar .playback-bar .progress-bar__slider'); | |
| progressBarBtn.css('left', '0%'); | |
| } | |
| // register handling for keybindings | |
| document.addEventListener('keydown', event => { | |
| let key = event.key.toLowerCase(); | |
| if (key == 'control') { | |
| buffer = []; | |
| } | |
| if (buffer.last() != key) { | |
| buffer.push(key); | |
| } | |
| bindings.filter(function (item) { | |
| if (arraysMatch(item.binding, buffer)) { | |
| item.action(); | |
| } | |
| }); | |
| }); | |
| // Interact with navigation somehow | |
| window.addEventListener('loadstart', function (event) { | |
| console.log('loadstart event'); | |
| console.log(event); | |
| }); | |
| window.addEventListener('loadstop', function (event) { | |
| console.log('loadstop event'); | |
| console.log(event); | |
| }); | |
| // register interval handler for tracklist highliting | |
| setInterval(highlightCurrentlyPLaying, '1s'); | |
| setInterval(enforceAdjustedPlaylistHeight, '3s'); | |
| })(); |
Author
Author
TODO :: [ control ] + [ alt ] + [ a ] -- scroll curently playing song into view ( in case not on playing playlist jump to it )
Author
Small patch to __jumpToPlaylist() due to failing execution
Author
Noticed disfunction and fixed a number of the key bindings to reflect said changes
Changed timeout of song switcher in order to make it able to switch songs when away from the currently playing playlist
- unintended behavior is great delay when used whilst the playlist is active
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
TODO :: update next & prev to navigate to current playlist, hit play on next song then hit back on the nav to return the user to where he was watching