Playlists buttons V3

Adds Buttons to your favorite playlists, and extra functionality.

当前为 2023-07-02 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Playlists buttons V3
  3. // @version 3.1
  4. // @description Adds Buttons to your favorite playlists, and extra functionality.
  5. // @author Bliwi
  6. // @match https://soundcloud.com/*
  7. // @grant none
  8. // @run-at document-end
  9. // @noframes
  10. // @license MIT
  11. // @namespace https://greasyfork.org/users/943433
  12. // ==/UserScript==
  13.  
  14. (function() {
  15. 'use strict';
  16. let smallArtglobal = '';
  17. let globalAccent = '';
  18. var root = document.documentElement;
  19. //Load things
  20.  
  21. setTimeout(function welcome(){
  22. root.style.setProperty('--welcome', 'none');
  23. }, 100);
  24. var savedUrls = JSON.parse(localStorage.getItem('urls'));
  25. var savedNames = JSON.parse(localStorage.getItem('names'));
  26. let currentPage = location.href;
  27. setTimeout(playlistsLoad, 500);
  28. setInterval(function()
  29. {
  30.  
  31. // Interval function. Put stuff you want to check every 500 miliseconds.
  32. if(!document.querySelector('.pinbutton')){
  33. if(window.location.href.indexOf("com/you/sets") != -1){
  34. pinToSidebar();
  35. }
  36. var parentElement = document.querySelector('.playbackSoundBadge');
  37. let small = parentElement.querySelector('span.sc-artwork.sc-artwork-4x');
  38. let localAccent = getComputedStyle(document.documentElement).getPropertyValue('--accent');
  39. let smallArt = small.style.backgroundImage;
  40. const styles = getComputedStyle(document.documentElement);
  41. const floating = styles.getPropertyValue('--floating-accent');
  42. if(smallArt != smallArtglobal && floating == 1){
  43. console.log('they are not equal',smallArtglobal);
  44. smallArtglobal = smallArt;
  45. let filteredUrl = smallArt.replace('url("', '').replace('")', '');
  46.  
  47. generateAccentColor(filteredUrl, function(accentColor) {
  48. console.log('Accent Color:', accentColor);
  49. let rgbAccent = 'rgb('+accentColor+')'
  50. root.style.setProperty('--accent', rgbAccent);
  51. var meta = document.querySelector('meta[name="theme-color"]');
  52. setTimeout(meta.setAttribute("content", rgbAccent),30);
  53. });
  54. } else if (localAccent != globalAccent) {
  55. console.log('they are not equal',localAccent);
  56. globalAccent = localAccent;
  57. var meta = document.querySelector('meta[name="theme-color"]');
  58. meta.setAttribute("content", localAccent);
  59. }
  60. };
  61. //add the future lazy load fix in here
  62. }, 500);
  63.  
  64. //console.log(savedNames);
  65.  
  66. // Floating-app theme frame
  67.  
  68. appTheme('app-theme-top','#app');
  69. appTheme('app-theme-background','#app');
  70. setTimeout(appTheme('app-theme-corner-1','.app-theme-top'), 1);
  71. setTimeout(appTheme('app-theme-corner-2','.app-theme-top'), 1);
  72. setTimeout(appTheme('app-theme-corner-3','.app-theme-top'), 1);
  73. setTimeout(appTheme('app-theme-corner-4','.app-theme-top'), 1);
  74. setTimeout(appTheme('app-theme-shadow','.app-theme-top'), 1);
  75. setTimeout(appTheme('app-theme-bottom','.app-theme-top'), 1);
  76. setTimeout(appTheme('app-theme-left','.app-theme-top'), 1);
  77. setTimeout(appTheme('app-theme-right','.app-theme-top'), 1);
  78. function appTheme(a,b){
  79. let thing = document.createElement('a');
  80. let parent = document.querySelector(b);
  81. thing.className = a;
  82. parent.insertBefore(thing, parent.children[2]);
  83. };
  84.  
  85. //add new playlist button
  86. function pinToSidebar() {
  87. //Pin button
  88.  
  89. let button = document.createElement('a');
  90. let header = document.querySelector('.collectionSection__flexFill');
  91. button.className = 'pinbutton';
  92. button.innerHTML = '📌';
  93. button.title = 'Pin all the playlists';
  94. header.insertBefore(button, header.children[2]);
  95.  
  96.  
  97. //Clear
  98.  
  99. setTimeout(function clear(){
  100. let button = document.createElement('a');
  101. let header = document.querySelector('.collectionSection__flexFill');
  102. button.className = 'pinbutton';
  103. button.innerHTML = '🗑️';
  104. button.title = 'Remove all the playlists from the sidebar';
  105. header.insertBefore(button, header.children[2]);
  106. button.onclick = function (){
  107. if (confirm("Are you sure you want to remove all the pinned playlists?")){
  108. var savedUrls = [];
  109. var savedNames = [];
  110. localStorage.setItem('names', JSON.stringify(savedNames));
  111. localStorage.setItem('urls', JSON.stringify(savedUrls));
  112. location.reload();}
  113. }
  114. },10)
  115.  
  116. //Plus Button
  117.  
  118. setTimeout(
  119. function plus() {
  120. let button = document.createElement('a');
  121. let header = document.querySelector('.collectionSection__flexFill');
  122. button.className = 'pinbutton';
  123. button.innerHTML = '➕';
  124. button.title = 'Add a single playlist to the sidebar.';
  125. header.insertBefore(button, header.children[2]);
  126. button.onclick = function (){
  127. var newName = prompt('Enter the name of the playlist:');
  128. if (newName) {
  129. var newURL = prompt('Enter the URL for the playlist:');
  130. if (newURL) {
  131.  
  132. var modifiedUrl = newURL.replace('https://soundcloud.com', '').replace('http://soundcloud.com', '');
  133. savedUrls.push(modifiedUrl);
  134. savedNames.push(newName);
  135. console.log(savedNames);
  136. console.log(savedUrls);
  137.  
  138. localStorage.setItem('names', JSON.stringify(savedNames));
  139. localStorage.setItem('urls', JSON.stringify(savedUrls));
  140. if (confirm("Done pinning,Soundfy will now reload to take effect.")){location.reload();}
  141. }
  142. }
  143. }
  144. },
  145. 10);
  146.  
  147. //Extract the playlists
  148. button.onclick = function (){
  149. setInterval(window.scrollTo(0,document.body.scrollHeight - 1200), 10);
  150. button.innerHTML = 'Extracting the playlists';
  151. setTimeout(function done(){
  152. if (confirm("Done pinning,Soundfy will now reload to take effect.")){location.reload();}
  153. },1000)
  154. // Query the elements on the page
  155. var elements = document.querySelectorAll('a.sc-link-primary.sc-link-dark.sc-type-light.sc-text-secondary.playableTile__mainHeading.playableTile__heading.audibleTile__audibleHeading.sc-truncate.sc-font-light.sc-text-h4');
  156. // Store the URLs in variables
  157. //
  158. var urls = [];
  159. var names = [];
  160. for (var i = 0; i < elements.length; i++) {
  161. let button = document.createElement('a');
  162. let header = document.querySelector('.collectionSection__top');
  163. header.style.display = "block !important";
  164. button.innerHTML = modnames3;
  165. header.insertBefore(button, header.children[2]);
  166. button.className = 'playlist-name';
  167. var url = elements[i].href;
  168. var modifiedUrl = url.replace('https://soundcloud.com', '').replace('http://soundcloud.com', '');
  169. var modnames = url.replace('https://soundcloud.com/', '').replace('http://soundcloud.com/', '');
  170. var modnames2 = modnames.replace('-', ' ').replace('-', ' ');
  171. var modnames3 = modnames2.replace('/sets/', ' - ').replace('/sets/', ' - ');
  172. names.push(modnames3);
  173. urls.push(modifiedUrl);
  174. }
  175. console.log(urls);
  176. console.log(names);
  177. //Save the Urls and names to the local storage
  178. //
  179. localStorage.setItem('urls', JSON.stringify(urls));
  180. localStorage.setItem('names', JSON.stringify(names));
  181.  
  182. };
  183.  
  184. }
  185.  
  186. //functions
  187. //Load the playlists
  188. function playlistsLoad() {
  189. let container = document.createElement('div');
  190. let header = document.querySelector('.header');
  191. container.className = 'container';
  192. container.id = 'iframe-container';
  193. header.insertBefore(container, header.children[2]);
  194. for (var i = 0; i < savedUrls.length; i++) {
  195. var url = savedUrls[i];
  196. var name = savedNames[i];
  197. insertButton(name,url);
  198. }
  199. }
  200. //Insert the buttons
  201. function insertButton(playlistname,playlistlink) {
  202. let playlist = document.createElement('a');
  203. let header = document.querySelector('.container');
  204. const i = savedNames.indexOf(playlistname);
  205. playlist.id = i;
  206. playlist.innerHTML = playlistname;
  207. playlist.className = 'playlist-button';
  208. playlist.href = playlistlink;
  209.  
  210. //Delete or rename
  211. playlist.ondblclick = function() {
  212. var newName = prompt('Enter a new name(del to delete):');
  213. if (newName === 'del') {
  214. //delete savedNames[i];
  215. savedNames.splice(i, 1);
  216. savedUrls.splice(i, 1);
  217. playlist.className = '';
  218. playlist.innerHTML = '';
  219. playlist.href = '';
  220. console.log(savedNames);
  221. localStorage.setItem('names', JSON.stringify(savedNames));
  222. localStorage.setItem('urls', JSON.stringify(savedUrls));
  223. } else if (newName) {
  224. // Rename
  225. playlist.innerHTML = newName;
  226. savedNames[i] = newName;
  227. console.log(savedNames);
  228. localStorage.setItem('names', JSON.stringify(savedNames));
  229. }
  230. }
  231. if (header) {
  232. header.insertBefore(playlist, header.children[2]);
  233.  
  234. } else {setTimeout(playlistsLoad, 1000);}
  235. }
  236.  
  237. //Generate accent color
  238.  
  239. function generateAccentColor(imageUrl, callback) {
  240. var img = new Image();
  241. img.crossOrigin = 'Anonymous';
  242. img.onload = function() {
  243. var canvas = document.createElement('canvas');
  244. canvas.width = img.width;
  245. canvas.height = img.height;
  246.  
  247. var ctx = canvas.getContext('2d');
  248. ctx.drawImage(img, 0, 0);
  249.  
  250. var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
  251. var data = imageData.data;
  252.  
  253. var colorCounts = {};
  254. var maxCount = 0;
  255. var dominantColor;
  256.  
  257. // Loop through the image pixels and count the occurrences of each color
  258. for (var i = 0; i < data.length; i += 4) {
  259. var r = data[i];
  260. var g = data[i + 1];
  261. var b = data[i + 2];
  262.  
  263. var rgb = r + ',' + g + ',' + b;
  264.  
  265. if (colorCounts[rgb]) {
  266. colorCounts[rgb]++;
  267. } else {
  268. colorCounts[rgb] = 1;
  269. }
  270.  
  271. if (colorCounts[rgb] > maxCount) {
  272. maxCount = colorCounts[rgb];
  273. dominantColor = rgb;
  274. }
  275. }
  276.  
  277. // Return the dominant color
  278. callback(dominantColor);
  279. };
  280.  
  281. // Load the image
  282. img.src = imageUrl;
  283. }
  284.  
  285. })();