// ==UserScript==
// @name MixesDB Userscripts Helper (by MixesDB)
// @author User:Martin@MixesDB (Subfader@GitHub)
// @version 2025.08.20.1
// @description Change the look and behaviour of the MixesDB website to enable feature usable by other MixesDB userscripts.
// @homepageURL https://www.mixesdb.com/w/Help:MixesDB_userscripts
// @supportURL https://discord.com/channels/1258107262833262603/1293952534268084234
// @updateURL https://cdn.rawgit.com/mixesdb/userscripts/refs/heads/main/MixesDB_Userscripts_Helper/script.user.js
// @downloadURL https://raw.githubusercontent.com/mixesdb/userscripts/refs/heads/main/MixesDB_Userscripts_Helper/script.user.js
// @require https://cdn.rawgit.com/mixesdb/userscripts/refs/heads/main/includes/jquery-3.7.1.min.js
// @require https://cdn.rawgit.com/mixesdb/userscripts/refs/heads/main/includes/waitForKeyElements.js
// @require https://raw.githubusercontent.com/mixesdb/userscripts/refs/heads/main/includes/global.js?v-MixesDB_Userscripts_Helper_13
// @require https://raw.githubusercontent.com/mixesdb/userscripts/refs/heads/main/includes/toolkit.js?v-MixesDB_Userscripts_Helper_3
// @match https://www.mixesdb.com/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=mixesdb.com
// @noframes
// @grant unsafeWindow
// @run-at document-end
// ==/UserScript==
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* User settings
* You need to set these on each update, but updates happen rarely for this script
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Apple Music settings
*/
// Apple Music links: force to open in browser?
// Keep 0 to use open the Music app
// Set 1 to open as normal browser tab on beta.music.apple.com (recommended)
const appleMusic_linksOpenInBrowser = 1; // default: 0
// Your Apple Music counry code, e.g. "de"
// All country codes: https://www.hiresedition.com/apple-music-country-codes.html
const appleMusic_countryCode_switch = "de"; // default: ""
/*
* TrackId.net settings
*/
// Submit player URLs to the TID request form
// * On Explorer mix results add an icon to the title bar
// * On mix pages add TID links to every player ("Exists" or "Submit")
// Set 0 to disable
const trackIdnet_addLinks = 1; // default: 1
/*
* Apple Podcasts settings
*/
// Add search icons for Apple Podcasts to mix page title icons and Explorer mix results
// Set 0 to disable
const applePodcasts_addSearchIcons = 1; // default: 1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Load @ressource files with variables
* global.js URL needs to be changed manually
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * */
var cacheVersion = 7,
scriptName = "MixesDB_Userscripts_Helper";
//loadRawCss( githubPath_raw + "includes/global.css?v-" + scriptName + "_" + cacheVersion );
loadRawCss( githubPath_raw + scriptName + "/script.css?v-" + cacheVersion );
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Basic functions
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * */
// getKeywordsFromTitle
function getKeywordsFromTitle( titleWrapper ) {
return normalizeTitleForSearch( titleWrapper.text() );
}
// function getKeywordsFromTitle_Customized_AP
// Customize keywords for more precise results
function getKeywordsFromTitle_Customized_AP( titleWrapper ) {
var title = titleWrapper.text(),
keywords = getKeywordsFromTitle( titleWrapper );
if( title.match(/Resident Advisor \(RA\.\d+\)/) ) {
keywords = title.replace( /^.+ - (.+) - Resident Advisor \((RA\.\d+)\)/g, "$2 $1");
}
return keywords;
}
// get applePodcastsSearchLink
function getApplePodcastsSearchLink( className, keywords ) {
var applePodcastsSearchUrl = "https://podcasts.apple.com/us/search?term="+encodeURIComponent( keywords );
// mak eicon link
// max-height to avoid flashing original icon size (script.css loads later)
var iconLink = '';
return iconLink;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Mix page title icons and Explorer title icons fpr
** TrackId.net request submission
** Apple Podcasts search
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * */
logFunc( "Quicker Submit Request" );
d.ready(function(){ // needed for mw.config
// Prepare variables to check if we're on a mix page etc.
var actionView = $("body").hasClass("action-view") ? true : false,
wgNamespaceNumber = mw.config.get("wgNamespaceNumber"),
wgTitle = mw.config.get("wgTitle"),
wgPageName = mw.config.get("wgPageName");
/*
* On mix pages and MixesDB:Explorer/Mixes
* Also allow on page edit (preview)
*/
if( trackIdnet_addLinks
&& ( wgNamespaceNumber==0 && wgTitle!="Main Page" )
|| ( wgNamespaceNumber==4 && wgPageName=="MixesDB:Explorer/Mixes" )
) {
log( "Criteria for mix page matched." );
/*
* TrackId.net submit link under each player
*/
$(".playerWrapper[data-playersite]").each(function(){
var playerWrapper = $(this),
playerTidCompatible = playerWrapper.attr("data-tidcompatibleplayersite"),
playerUrl = playerWrapper.attr("data-playerurl"),
playerSite = makeCssSafe( playerWrapper.attr("data-playersite") ),
keywords = "";
logVar( "playerSite", playerSite );
logVar( "playerUrl", playerUrl );
// Remove URL paramteres from e.g. SoundCloud and Mixcloud
if( playerSite != "YouTube" ) {
playerUrl = removeParametersFromUrl( playerWrapper.attr("data-playerurl") );
} else {
playerUrl = playerUrl.replace( "www.youtu.be", "youtu.be" );
}
if( playerSite == "hearthis-at" ) {
playerUrl = playerUrl.replace( "hearthis.audio", "hearthis.at" );
}
// if mix page
if( wgNamespaceNumber==0 && wgTitle!="Main Page" ) {
keywords = getKeywordsFromTitle( $("h1#firstHeading") )
}
// if Explorer/Mixes
if( wgNamespaceNumber==4 && wgPageName=="MixesDB:Explorer/Mixes" ) {
var explorerResult = playerWrapper.closest(".explorerResult"),
explorerResult_title = $(".playerLink", explorerResult).attr("title");
keywords = normalizeTitleForSearch( explorerResult_title );
}
if( playerTidCompatible == "true" ) {
// check usage
var apiQueryUrl_check = apiUrl_mw;
apiQueryUrl_check += "?action=mixesdbtrackid";
apiQueryUrl_check += "&format=json";
apiQueryUrl_check += "&url=" + playerUrl;
logVar( "apiQueryUrl_check", apiQueryUrl_check );
$.ajax({
url: apiQueryUrl_check,
type: 'get', /* GET on checking */
dataType: 'json',
async: true,
success: function(data) {
// avoid undefined error
if( ( data.error && data.error.code == "notfound" ) ) {
// no result
var tidLink_submit = 'Submit to TrackId.net';
playerWrapper.append( '