|
1 | 1 | // ==UserScript== |
2 | 2 | // @name Musicbrainz UI enhancements |
3 | 3 | // @description Various UI enhancements for Musicbrainz |
4 | | -// @version 2026.7.23.1 |
| 4 | +// @version 2026.8.25.1 |
5 | 5 | // @downloadURL https://raw.githubusercontent.com/murdos/musicbrainz-userscripts/master/mb_ui_enhancements.user.js |
6 | 6 | // @updateURL https://raw.githubusercontent.com/murdos/musicbrainz-userscripts/master/mb_ui_enhancements.user.js |
7 | 7 | // @icon http://wiki.musicbrainz.org/images/3/3d/Musicbrainz_logo.png |
|
16 | 16 | // @resource errorIcon https://raw.githubusercontent.com/murdos/musicbrainz-userscripts/master/assets/icons/error.svg?v=2026.2.12.3 |
17 | 17 | // @resource searchIcon https://raw.githubusercontent.com/murdos/musicbrainz-userscripts/master/assets/icons/search.svg?v=2026.2.12.3 |
18 | 18 | // @resource searchArtistIcon https://raw.githubusercontent.com/murdos/musicbrainz-userscripts/master/assets/icons/search-artist.svg?v=2026.2.12.3 |
| 19 | +// @resource harmonyIcon https://harmony.pulsewidth.org.uk/favicon.svg?v=2026.8.25.3 |
19 | 20 | // @grant GM_getResourceURL |
20 | 21 | // @grant GM_registerMenuCommand |
21 | 22 | // @grant GM_getValue |
@@ -621,37 +622,47 @@ $(document).ready(function () { |
621 | 622 | } |
622 | 623 | } |
623 | 624 |
|
624 | | - // Display a-tisket links next to Deezer, Spotify, iTunes and Apple Music links |
625 | | - if (window.location.href.match(releaseRegex)) { |
626 | | - document.querySelectorAll('div#bottom-credits a').forEach(function (link) { |
627 | | - if (link.href.match(/deezer.com|(music|itunes).apple.com|spotify.com/)) { |
628 | | - let id; |
629 | | - let fragment; |
630 | | - let country; |
631 | | - if (link.href.match(/deezer.com/)) { |
632 | | - id = new URL(link.href).pathname.split('/').slice(-1)[0]; |
633 | | - fragment = 'deez'; |
634 | | - country = 'GB%2CUS%2CIN'; |
635 | | - } else if (link.href.match(/apple.com/)) { |
636 | | - id = new URL(link.href).pathname.split('/', 5).slice(-1)[0].replace('id', ''); |
637 | | - fragment = 'itu'; |
638 | | - country = new URL(link.href).pathname.split('/', 2)[1]; |
639 | | - } else if (link.href.match(/spotify.com/)) { |
640 | | - id = new URL(link.href).pathname.split('/', 5).slice(-1)[0]; |
641 | | - fragment = 'spf'; |
642 | | - country = 'GB%2CUS%2CIN'; |
643 | | - } |
644 | | - |
645 | | - let next = link.nextElementSibling.nextElementSibling; |
646 | | - let newlink = document.createElement('a'); |
647 | | - newlink.href = `https://atisket.pulsewidth.org.uk/?preferred_countries=${country}&${fragment}_id=${id}&preferred_vendor=${fragment}`; |
648 | | - newlink.text = 'a-tisket'; |
649 | | - |
650 | | - next.before(document.createTextNode(' [')); |
651 | | - next.before(newlink); |
652 | | - next.before(document.createTextNode(']')); |
653 | | - } |
654 | | - }); |
| 625 | + // Display a Harmony lookup link when the release has a supported provider URL |
| 626 | + const releaseMatch = window.location.href.match(releaseRegex); |
| 627 | + if (releaseMatch) { |
| 628 | + const harmonyProviderHostname = |
| 629 | + /^(?:[^.]+\.bandcamp\.com|www\.beatport\.com|music\.bugs\.co\.kr|(?:www\.)?deezer\.com|www\.discogs\.com|(?:geo\.)?(?:itunes|music)\.apple\.com|(?:www|m2)\.melon\.com|mora\.jp|ototoy\.jp|(?:play|www|open)\.qobuz\.com|open\.spotify\.com|(?:(?:www|listen)\.)?tidal\.com)$/i; |
| 630 | + const barcode = document.querySelector('#sidebar dd.barcode')?.textContent.trim(); |
| 631 | + const validGtin = |
| 632 | + barcode && /^(?:\d{8}|\d{12,14})$/.test(barcode) |
| 633 | + ? barcode |
| 634 | + .split('') |
| 635 | + .reduce((checksum, digit, index) => checksum + Number(digit) * ((barcode.length - index) % 2 ? 1 : 3), 0) % |
| 636 | + 10 === |
| 637 | + 0 |
| 638 | + : false; |
| 639 | + const externalLinks = document.querySelector('#sidebar h2.external-links + ul.external_links'); |
| 640 | + |
| 641 | + const supportedProviderUrls = Array.from(externalLinks?.querySelectorAll('li a[href]') ?? []) |
| 642 | + .map(link => new URL(link.href)) |
| 643 | + .filter(url => harmonyProviderHostname.test(url.hostname)); |
| 644 | + const lowerPriorityHostname = /^(?:[^.]+\.bandcamp\.com|www\.beatport\.com|(?:geo\.)?(?:itunes|music)\.apple\.com)$/i; |
| 645 | + const providerUrl = supportedProviderUrls.find(url => !lowerPriorityHostname.test(url.hostname)) ?? supportedProviderUrls[0]; |
| 646 | + |
| 647 | + if (providerUrl) { |
| 648 | + const harmonyUrl = new URL('https://harmony.pulsewidth.org.uk/release'); |
| 649 | + harmonyUrl.searchParams.set('url', providerUrl.href); |
| 650 | + harmonyUrl.searchParams.set('category', 'preferred'); |
| 651 | + harmonyUrl.searchParams.set('musicbrainz', releaseMatch[1]); |
| 652 | + if (validGtin) harmonyUrl.searchParams.set('gtin', barcode); |
| 653 | + |
| 654 | + const harmonyLink = document.createElement('a'); |
| 655 | + harmonyLink.href = harmonyUrl.href; |
| 656 | + harmonyLink.target = '_blank'; |
| 657 | + harmonyLink.rel = 'noopener'; |
| 658 | + harmonyLink.textContent = 'Lookup with Harmony'; |
| 659 | + |
| 660 | + const harmonyItem = document.createElement('li'); |
| 661 | + harmonyItem.style.backgroundImage = `url("${GM_getResourceURL('harmonyIcon')}")`; |
| 662 | + harmonyItem.style.backgroundSize = '16px 16px'; |
| 663 | + harmonyItem.appendChild(harmonyLink); |
| 664 | + externalLinks.appendChild(harmonyItem); |
| 665 | + } |
655 | 666 | } |
656 | 667 |
|
657 | 668 | // Discogs link rollover |
|
0 commit comments