From 2b67fc2609e2502751c9c8d9b1e28fbe38681830 Mon Sep 17 00:00:00 2001 From: ".vlad" <119420130+vladbrox@users.noreply.github.com> Date: Fri, 27 Mar 2026 18:45:57 +0300 Subject: [PATCH 1/3] Fix condition in loveTrack method --- js/listenbrainz.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/listenbrainz.js b/js/listenbrainz.js index e894a61..0310c16 100644 --- a/js/listenbrainz.js +++ b/js/listenbrainz.js @@ -249,7 +249,7 @@ export class ListenBrainzScrobbler { } async loveTrack(track) { - if (!track.artist?.name || track.title) return; + if (!track.artist?.name || !track.title) return; const trackKey = `${track.artist.name}-${track.title}`; if (!this.isEnabled() || this.lovingTracks.has(trackKey)) return; this.lovingTracks.add(trackKey); From e809d1443f4f43bbd7dcdbb2ed4d72b72f19bf92 Mon Sep 17 00:00:00 2001 From: Eduard Prigoana Date: Sat, 28 Mar 2026 01:04:30 +0200 Subject: [PATCH 2/3] fix trackers, remove AI slop --- INSTANCES.md | 46 +++++--------- functions/album/[id].js | 8 ++- functions/artist/[id].js | 2 +- functions/playlist/[id].js | 7 ++- functions/podcasts/[id].js | 98 +++++++++++++++++++++++++++++ functions/track/[id].js | 2 +- functions/user/@[username].js | 2 +- functions/userplaylist/[id].js | 111 +++++++++++++++++++++++++++++++++ index.html | 18 ------ js/settings.js | 9 --- js/storage.js | 56 +++++++---------- js/tracker.js | 2 +- 12 files changed, 257 insertions(+), 104 deletions(-) create mode 100644 functions/podcasts/[id].js create mode 100644 functions/userplaylist/[id].js diff --git a/INSTANCES.md b/INSTANCES.md index 399ff12..3fac04f 100644 --- a/INSTANCES.md +++ b/INSTANCES.md @@ -18,48 +18,30 @@ The official Monochrome instance maintained by the core team: ## Community Instances -### Community Monochrome Instances - -These instances are community instances of Monochrome & its WebUI: - -| Provider | URL | Status | -| ------------- | ---------------------------------------- | --------- | -| **Squid.WTF** | [mono.squid.wtf](https://mono.squid.wtf) | Community | - -### UI-Only Instances - -These instances provide the tidal-ui web interface, not monochrome: - -| Provider | URL | Status | -| ------------- | ------------------------------------------- | --------- | -| **squid.wtf** | [tidal.squid.wtf](https://tidal.squid.wtf) | Community | -| **QQDL** | [tidal.qqdl.site](https://tidal.qqdl.site/) | Community | - ---- +PLEASE do not use any rehost of monochrome and complain to us about features not working. They are usually out of date, and do not provide the latest features, and accounts are always broken. ## API Instances Monochrome uses the Hi-Fi API under the hood. Live, up-to-date status trackers (which return JSON) can be found below: -- https://tidal-uptime.jiffy-puffs-1j.workers.dev/ -- https://tidal-uptime.props-76styles.workers.dev/ +- [https://tidal-uptime.jiffy-puffs-1j.workers.dev](https://tidal-uptime.jiffy-puffs-1j.workers.dev/) +- [https://tidal-uptime.props-76styles.workers.dev](https://tidal-uptime.props-76styles.workers.dev/) These are available API endpoints that can be used with Monochrome or other Hi-Fi based applications: ### Official & Community APIs -| Provider | URL | Notes | -| ----------------- | ----------------------------------- | ----------------------------------------------------------------------- | -| **Monochrome** | `https://monochrome-api.samidy.com` | Official API | -| | `https://api.monochrome.tf` | Official API | -| | `https://arran.monochrome.tf` | Official API | -| **squid.wtf** | `https://triton.squid.wtf` | Community hosted | -| **Lucida (QQDL)** | `https://wolf.qqdl.site` | Community hosted | -| | `https://maus.qqdl.site` | Community hosted | -| | `https://vogel.qqdl.site` | Community hosted | -| | `https://katze.qqdl.site` | Community hosted | -| | `https://hund.qqdl.site` | Community hosted | -| **Kinoplus** | `https://tidal.kinoplus.online` | Community hosted - [Limited/No-Sub](https://rentry.co/limitedtidalaccs) | +| Provider | URL | Notes | +| ----------------- | ----------------------------------- | ------------------------------------------------------------------------------------------------------ | +| **Monochrome** | `https://monochrome-api.samidy.com` | Official API | +| | `https://api.monochrome.tf` | Official API | +| **geeked.wtf** | `https://hifi.geeked.wtf` | Community hosted - uses the [TypeScript Rewrite](https://github.com/monochrome-music/hifi-api-workers) | +| **Lucida (QQDL)** | `https://wolf.qqdl.site` | Community hosted | +| | `https://maus.qqdl.site` | Community hosted | +| | `https://vogel.qqdl.site` | Community hosted | +| | `https://katze.qqdl.site` | Community hosted | +| | `https://hund.qqdl.site` | Community hosted | +| **Kinoplus** | `https://tidal.kinoplus.online` | Community hosted - [Limited/No-Sub](https://rentry.co/limitedtidalaccs) | --- diff --git a/functions/album/[id].js b/functions/album/[id].js index 5f73a01..4149399 100644 --- a/functions/album/[id].js +++ b/functions/album/[id].js @@ -72,16 +72,18 @@ class ServerAPI { } if (data) { - this.apiInstances = (data.api || []).map((item) => item.url || item); + this.apiInstances = (data.api || []) + .map((item) => item.url || item) + .filter((url) => !/\.squid\.wtf/i.test(url)); return this.apiInstances; } console.error('Failed to load instances from all uptime APIs'); return [ + 'https://hifi.geeked.wtf', 'https://eu-central.monochrome.tf', 'https://us-west.monochrome.tf', 'https://arran.monochrome.tf', - 'https://triton.squid.wtf', 'https://api.monochrome.tf', 'https://monochrome-api.samidy.com', 'https://maus.qqdl.site', @@ -135,7 +137,7 @@ class ServerAPI { export async function onRequest(context) { const { request, params, env } = context; const userAgent = request.headers.get('User-Agent') || ''; - const isBot = /discordbot|twitterbot|facebookexternalhit|bingbot|googlebot|slurp|whatsapp|pinterest|slackbot/i.test( + const isBot = /discordbot|twitterbot|facebookexternalhit|bingbot|googlebot|slurp|whatsapp|pinterest|slackbot|telegrambot|linkedinbot|mastodon|signal|snapchat|redditbot|skypeuripreview|viberbot|linebot|embedly|quora|outbrain|tumblr|duckduckbot|yandexbot|rogerbot|showyoubot|kakaotalk|naverbot|seznambot|mediapartners|adsbot|petalbot|applebot|ia_archiver/i.test( userAgent ); const albumId = params.id; diff --git a/functions/artist/[id].js b/functions/artist/[id].js index bef8df8..3179d80 100644 --- a/functions/artist/[id].js +++ b/functions/artist/[id].js @@ -135,7 +135,7 @@ class ServerAPI { export async function onRequest(context) { const { request, params, env } = context; const userAgent = request.headers.get('User-Agent') || ''; - const isBot = /discordbot|twitterbot|facebookexternalhit|bingbot|googlebot|slurp|whatsapp|pinterest|slackbot/i.test( + const isBot = /discordbot|twitterbot|facebookexternalhit|bingbot|googlebot|slurp|whatsapp|pinterest|slackbot|telegrambot|linkedinbot|mastodon|signal|snapchat|redditbot|skypeuripreview|viberbot|linebot|embedly|quora|outbrain|tumblr|duckduckbot|yandexbot|rogerbot|showyoubot|kakaotalk|naverbot|seznambot|mediapartners|adsbot|petalbot|applebot|ia_archiver/i.test( userAgent ); const artistId = params.id; diff --git a/functions/playlist/[id].js b/functions/playlist/[id].js index f254bf5..9f96053 100644 --- a/functions/playlist/[id].js +++ b/functions/playlist/[id].js @@ -72,7 +72,9 @@ class ServerAPI { } if (data) { - this.apiInstances = (data.api || []).map((item) => item.url || item); + this.apiInstances = (data.api || []) + .map((item) => item.url || item) + .filter((url) => !/\.squid\.wtf/i.test(url)); return this.apiInstances; } @@ -81,7 +83,6 @@ class ServerAPI { 'https://eu-central.monochrome.tf', 'https://us-west.monochrome.tf', 'https://arran.monochrome.tf', - 'https://triton.squid.wtf', 'https://api.monochrome.tf', 'https://monochrome-api.samidy.com', 'https://maus.qqdl.site', @@ -135,7 +136,7 @@ class ServerAPI { export async function onRequest(context) { const { request, params, env } = context; const userAgent = request.headers.get('User-Agent') || ''; - const isBot = /discordbot|twitterbot|facebookexternalhit|bingbot|googlebot|slurp|whatsapp|pinterest|slackbot/i.test( + const isBot = /discordbot|twitterbot|facebookexternalhit|bingbot|googlebot|slurp|whatsapp|pinterest|slackbot|telegrambot|linkedinbot|mastodon|signal|snapchat|redditbot|skypeuripreview|viberbot|linebot|embedly|quora|outbrain|tumblr|duckduckbot|yandexbot|rogerbot|showyoubot|kakaotalk|naverbot|seznambot|mediapartners|adsbot|petalbot|applebot|ia_archiver/i.test( userAgent ); const playlistId = params.id; diff --git a/functions/podcasts/[id].js b/functions/podcasts/[id].js new file mode 100644 index 0000000..4255018 --- /dev/null +++ b/functions/podcasts/[id].js @@ -0,0 +1,98 @@ +// functions/podcasts/[id].js + +const PODCASTINDEX_API_BASE = 'https://api.podcastindex.org/api/1.0'; +const PODCAST_API_KEY = 'YU5HMSDYBQQVYDF6QN4P'; +const PODCAST_API_SECRET = '8hCvpjSL7T$S7^5ftnf5MhqQwYUYVjM^fmUL3Ld$'; + +async function sha1(str) { + const encoder = new TextEncoder(); + const data = encoder.encode(str); + const hashBuffer = await crypto.subtle.digest('SHA-1', data); + const hashArray = Array.from(new Uint8Array(hashBuffer)); + return hashArray.map((b) => b.toString(16).padStart(2, '0')).join(''); +} + +async function getAuthHeaders() { + const apiHeaderTime = Math.floor(Date.now() / 1000).toString(); + const combined = PODCAST_API_KEY + PODCAST_API_SECRET + apiHeaderTime; + const authHeader = await sha1(combined); + return { + 'User-Agent': 'MonochromeMusic/1.0', + 'X-Auth-Key': PODCAST_API_KEY, + 'X-Auth-Date': apiHeaderTime, + Authorization: authHeader, + }; +} + +export async function onRequest(context) { + const { request, params, env } = context; + const userAgent = request.headers.get('User-Agent') || ''; + const isBot = /discordbot|twitterbot|facebookexternalhit|bingbot|googlebot|slurp|whatsapp|pinterest|slackbot|telegrambot|linkedinbot|mastodon|signal|snapchat|redditbot|skypeuripreview|viberbot|linebot|embedly|quora|outbrain|tumblr|duckduckbot|yandexbot|rogerbot|showyoubot|kakaotalk|naverbot|seznambot|mediapartners|adsbot|petalbot|applebot|ia_archiver/i.test( + userAgent + ); + const podcastId = params.id; + + if (isBot && podcastId) { + try { + const headers = await getAuthHeaders(); + const response = await fetch(`${PODCASTINDEX_API_BASE}/podcasts/byfeedid?id=${podcastId}&pretty`, { + method: 'GET', + headers, + }); + + if (!response.ok) throw new Error(`PodcastIndex error: ${response.status}`); + + const data = await response.json(); + const feed = data.status === 'true' && data.feed ? data.feed : null; + + if (feed && feed.title) { + const title = feed.title; + const author = feed.author || feed.ownerName || ''; + const episodeCount = feed.episodeCount || 0; + const rawDescription = feed.description || ''; + const description = author + ? `Podcast by ${author} • ${episodeCount} Episodes\nListen on Monochrome` + : `Podcast • ${episodeCount} Episodes\nListen on Monochrome`; + const imageUrl = feed.image || feed.artwork || 'https://monochrome.tf/assets/appicon.png'; + const pageUrl = new URL(request.url).href; + + const metaHtml = ` + + + + + ${title} + + + + + + + + + + + + + + + + +

${title}

+

${description}

+ Podcast Cover + + + `; + + return new Response(metaHtml, { headers: { 'content-type': 'text/html;charset=UTF-8' } }); + } + } catch (error) { + console.error(`Error for podcast ${podcastId}:`, error); + } + } + + const url = new URL(request.url); + url.pathname = '/'; + return env.ASSETS.fetch(new Request(url, request)); +} diff --git a/functions/track/[id].js b/functions/track/[id].js index bf2205d..033a936 100644 --- a/functions/track/[id].js +++ b/functions/track/[id].js @@ -165,7 +165,7 @@ class ServerAPI { export async function onRequest(context) { const { request, params, env } = context; const userAgent = request.headers.get('User-Agent') || ''; - const isBot = /discordbot|twitterbot|facebookexternalhit|bingbot|googlebot|slurp|whatsapp|pinterest|slackbot/i.test( + const isBot = /discordbot|twitterbot|facebookexternalhit|bingbot|googlebot|slurp|whatsapp|pinterest|slackbot|telegrambot|linkedinbot|mastodon|signal|snapchat|redditbot|skypeuripreview|viberbot|linebot|embedly|quora|outbrain|tumblr|duckduckbot|yandexbot|rogerbot|showyoubot|kakaotalk|naverbot|seznambot|mediapartners|adsbot|petalbot|applebot|ia_archiver/i.test( userAgent ); const trackId = params.id; diff --git a/functions/user/@[username].js b/functions/user/@[username].js index 507d9cd..32a0526 100644 --- a/functions/user/@[username].js +++ b/functions/user/@[username].js @@ -3,7 +3,7 @@ export async function onRequest(context) { const { request, params, env } = context; const userAgent = request.headers.get('User-Agent') || ''; - const isBot = /discordbot|twitterbot|facebookexternalhit|bingbot|googlebot|slurp|whatsapp|pinterest|slackbot/i.test( + const isBot = /discordbot|twitterbot|facebookexternalhit|bingbot|googlebot|slurp|whatsapp|pinterest|slackbot|telegrambot|linkedinbot|mastodon|signal|snapchat|redditbot|skypeuripreview|viberbot|linebot|embedly|quora|outbrain|tumblr|duckduckbot|yandexbot|rogerbot|showyoubot|kakaotalk|naverbot|seznambot|mediapartners|adsbot|petalbot|applebot|ia_archiver/i.test( userAgent ); const username = params.username; diff --git a/functions/userplaylist/[id].js b/functions/userplaylist/[id].js new file mode 100644 index 0000000..aa7a880 --- /dev/null +++ b/functions/userplaylist/[id].js @@ -0,0 +1,111 @@ +// functions/userplaylist/[id].js + +const POCKETBASE_URL = 'https://data.samidy.xyz'; +const PUBLIC_COLLECTION = 'public_playlists'; + +export async function onRequest(context) { + const { request, params, env } = context; + const userAgent = request.headers.get('User-Agent') || ''; + const isBot = /discordbot|twitterbot|facebookexternalhit|bingbot|googlebot|slurp|whatsapp|pinterest|slackbot|telegrambot|linkedinbot|mastodon|signal|snapchat|redditbot|skypeuripreview|viberbot|linebot|embedly|quora|outbrain|tumblr|duckduckbot|yandexbot|rogerbot|showyoubot|kakaotalk|naverbot|seznambot|mediapartners|adsbot|petalbot|applebot|ia_archiver/i.test( + userAgent + ); + const playlistId = params.id; + + if (isBot && playlistId) { + try { + const filter = `uuid="${playlistId}"`; + const apiUrl = `${POCKETBASE_URL}/api/collections/${PUBLIC_COLLECTION}/records?filter=${encodeURIComponent(filter)}&perPage=1`; + + const response = await fetch(apiUrl); + if (!response.ok) throw new Error(`PocketBase error: ${response.status}`); + + const result = await response.json(); + const record = result.items && result.items.length > 0 ? result.items[0] : null; + + if (record) { + let extraData = {}; + try { + extraData = record.data ? JSON.parse(record.data) : {}; + } catch { + extraData = {}; + } + + const title = record.title || record.name || (extraData && (extraData.title || extraData.name)) || 'Untitled Playlist'; + + let tracks = []; + try { + tracks = record.tracks ? JSON.parse(record.tracks) : []; + } catch { + tracks = []; + } + + const trackCount = tracks.length; + + let rawCover = record.image || record.cover || record.playlist_cover || ''; + if (!rawCover && extraData && typeof extraData === 'object') { + rawCover = extraData.cover || extraData.image || ''; + } + + let imageUrl = ''; + if (rawCover && (rawCover.startsWith('http') || rawCover.startsWith('data:'))) { + imageUrl = rawCover; + } else if (rawCover) { + imageUrl = `${POCKETBASE_URL}/api/files/${PUBLIC_COLLECTION}/${record.id}/${rawCover}`; + } + + if (!imageUrl && tracks.length > 0) { + const firstCover = tracks.find((t) => t.album?.cover)?.album?.cover; + if (firstCover) { + const formattedId = String(firstCover).replace(/-/g, '/'); + imageUrl = `https://resources.tidal.com/images/${formattedId}/1080x1080.jpg`; + } + } + + if (!imageUrl) { + imageUrl = 'https://monochrome.tf/assets/appicon.png'; + } + + const description = `Playlist • ${trackCount} Tracks\nListen on Monochrome`; + const pageUrl = new URL(request.url).href; + + const metaHtml = ` + + + + + ${title} + + + + + + + + + + + + + + + + + +

${title}

+

${description}

+ Playlist Cover + + + `; + + return new Response(metaHtml, { headers: { 'content-type': 'text/html;charset=UTF-8' } }); + } + } catch (error) { + console.error(`Error for user playlist ${playlistId}:`, error); + } + } + + const url = new URL(request.url); + url.pathname = '/'; + return env.ASSETS.fetch(new Request(url, request)); +} diff --git a/index.html b/index.html index 6e0c766..e5bcadb 100644 --- a/index.html +++ b/index.html @@ -1628,12 +1628,6 @@ GitHub - @@ -3155,18 +3149,6 @@ -
-
- Show Download in Sidebar - Display the Download link in the sidebar navigation -
- -
Show Discord in Sidebar diff --git a/js/settings.js b/js/settings.js index 1d4e71f..8f38924 100644 --- a/js/settings.js +++ b/js/settings.js @@ -2735,15 +2735,6 @@ export async function initializeSettings(scrobbler, player, api, ui) { }); } - const sidebarShowDownloadToggle = document.getElementById('sidebar-show-download-bottom-toggle'); - if (sidebarShowDownloadToggle) { - sidebarShowDownloadToggle.checked = sidebarSectionSettings.shouldShowDownload(); - sidebarShowDownloadToggle.addEventListener('change', (e) => { - sidebarSectionSettings.setShowDownload(e.target.checked); - sidebarSectionSettings.applySidebarVisibility(); - }); - } - const sidebarShowDiscordToggle = document.getElementById('sidebar-show-discordbtn-toggle'); if (sidebarShowDiscordToggle) { sidebarShowDiscordToggle.checked = sidebarSectionSettings.shouldShowDiscord(); diff --git a/js/storage.js b/js/storage.js index 570f1cc..6f8a0a4 100644 --- a/js/storage.js +++ b/js/storage.js @@ -77,28 +77,25 @@ export const apiSettings = { console.error('Failed to load instances from all uptime APIs:', fetchError); this.defaultInstances = { api: [ - { url: 'https://eu-central.monochrome.tf', version: '2.4' }, - { url: 'https://us-west.monochrome.tf', version: '2.4' }, - { url: 'https://arran.monochrome.tf', version: '2.4' }, - { url: 'https://triton.squid.wtf', version: '2.4' }, - { url: 'https://api.monochrome.tf', version: '2.3' }, + { url: 'https://hifi.geeked.wtf', version: '2.7' }, + { url: 'https://eu-central.monochrome.tf', version: '2.7' }, + { url: 'https://us-west.monochrome.tf', version: '2.7' }, + { url: 'https://api.monochrome.tf', version: '2.5' }, { url: 'https://monochrome-api.samidy.com', version: '2.3' }, - { url: 'https://maus.qqdl.site', version: '2.2' }, - { url: 'https://vogel.qqdl.site', version: '2.2' }, - { url: 'https://katze.qqdl.site', version: '2.2' }, - { url: 'https://hund.qqdl.site', version: '2.2' }, + { url: 'https://maus.qqdl.site', version: '2.6' }, + { url: 'https://vogel.qqdl.site', version: '2.6' }, + { url: 'https://katze.qqdl.site', version: '2.6' }, + { url: 'https://hund.qqdl.site', version: '2.6' }, { url: 'https://tidal.kinoplus.online', version: '2.2' }, { url: 'https://wolf.qqdl.site', version: '2.2' }, ], streaming: [ - { url: 'https://arran.monochrome.tf', version: '2.4' }, - { url: 'https://triton.squid.wtf', version: '2.4' }, - { url: 'https://maus.qqdl.site', version: '2.2' }, - { url: 'https://vogel.qqdl.site', version: '2.2' }, - { url: 'https://katze.qqdl.site', version: '2.2' }, - { url: 'https://hund.qqdl.site', version: '2.2' }, - { url: 'https://wolf.qqdl.site', version: '2.2' }, - { url: 'https://hifi.p1nkhamster.xyz/', version: '2.6' }, + { url: 'https://hifi.geeked.wtf', version: '2.7' }, + { url: 'https://maus.qqdl.site', version: '2.6' }, + { url: 'https://vogel.qqdl.site', version: '2.6' }, + { url: 'https://katze.qqdl.site', version: '2.6' }, + { url: 'https://hund.qqdl.site', version: '2.6' }, + { url: 'https://wolf.qqdl.site', version: '2.6' }, ], }; this.instancesLoaded = true; @@ -108,12 +105,17 @@ export const apiSettings = { let groupedInstances = { api: [], streaming: [] }; + const isBlockedInstance = (item) => { + const url = typeof item === 'string' ? item : item.url; + return url && /\.squid\.wtf/i.test(url); + }; + if (data.api && Array.isArray(data.api)) { - groupedInstances.api = data.api; + groupedInstances.api = data.api.filter((item) => !isBlockedInstance(item)); } if (data.streaming && Array.isArray(data.streaming)) { - groupedInstances.streaming = data.streaming; + groupedInstances.streaming = data.streaming.filter((item) => !isBlockedInstance(item)); } else if (groupedInstances.api.length > 0) { groupedInstances.streaming = [...groupedInstances.api]; } @@ -1806,7 +1808,6 @@ export const sidebarSectionSettings = { SHOW_DONATE_KEY: 'sidebar-show-donate', SHOW_SETTINGS_KEY: 'sidebar-show-settings', SHOW_ABOUT_KEY: 'sidebar-show-about', - SHOW_DOWNLOAD_KEY: 'sidebar-show-download', SHOW_DISCORD_KEY: 'sidebar-show-discord', SHOW_GITHUB_KEY: 'sidebar-show-github', ORDER_KEY: 'sidebar-menu-order', @@ -1818,7 +1819,6 @@ export const sidebarSectionSettings = { 'sidebar-nav-donate', 'sidebar-nav-settings', 'sidebar-nav-about-bottom', - 'sidebar-nav-download-bottom', 'sidebar-nav-discordbtn', 'sidebar-nav-githubbtn', ], @@ -1919,19 +1919,6 @@ export const sidebarSectionSettings = { localStorage.setItem(this.SHOW_ABOUT_KEY, enabled ? 'true' : 'false'); }, - shouldShowDownload() { - try { - const val = localStorage.getItem(this.SHOW_DOWNLOAD_KEY); - return val === null ? true : val === 'true'; - } catch { - return true; - } - }, - - setShowDownload(enabled) { - localStorage.setItem(this.SHOW_DOWNLOAD_KEY, enabled ? 'true' : 'false'); - }, - shouldShowDiscord() { try { const val = localStorage.getItem(this.SHOW_DISCORD_KEY); @@ -2016,7 +2003,6 @@ export const sidebarSectionSettings = { { id: 'sidebar-nav-donate', check: this.shouldShowDonate() }, { id: 'sidebar-nav-settings', check: this.shouldShowSettings() }, { id: 'sidebar-nav-about-bottom', check: this.shouldShowAbout() }, - { id: 'sidebar-nav-download-bottom', check: this.shouldShowDownload() }, { id: 'sidebar-nav-discordbtn', check: this.shouldShowDiscord() }, { id: 'sidebar-nav-githubbtn', check: this.shouldShowGithub() }, ]; diff --git a/js/tracker.js b/js/tracker.js index fe8350d..8c95654 100644 --- a/js/tracker.js +++ b/js/tracker.js @@ -107,7 +107,7 @@ function transformErasImages(eras) { } async function fetchTrackerData(sheetId) { - const endpoints = ['https://trackerapi-2.artistgrid.cx/get/', 'https://trackerapi-2.artistgrid.cx/get/']; + const endpoints = ['https://trackerapi-1.artistgrid.cx/get/', 'https://trackerapi-2.artistgrid.cx/get/']; let lastError = null; for (const baseUrl of endpoints) { From 499657a5f1aa7ace5b70034d43efaec6ed5360a0 Mon Sep 17 00:00:00 2001 From: edideaur <182119792+edideaur@users.noreply.github.com> Date: Fri, 27 Mar 2026 23:05:07 +0000 Subject: [PATCH 3/3] style: auto-fix linting issues --- functions/album/[id].js | 7 ++++--- functions/artist/[id].js | 7 ++++--- functions/playlist/[id].js | 7 ++++--- functions/podcasts/[id].js | 7 ++++--- functions/track/[id].js | 7 ++++--- functions/user/@[username].js | 7 ++++--- functions/userplaylist/[id].js | 13 +++++++++---- 7 files changed, 33 insertions(+), 22 deletions(-) diff --git a/functions/album/[id].js b/functions/album/[id].js index 4149399..b75c0bf 100644 --- a/functions/album/[id].js +++ b/functions/album/[id].js @@ -137,9 +137,10 @@ class ServerAPI { export async function onRequest(context) { const { request, params, env } = context; const userAgent = request.headers.get('User-Agent') || ''; - const isBot = /discordbot|twitterbot|facebookexternalhit|bingbot|googlebot|slurp|whatsapp|pinterest|slackbot|telegrambot|linkedinbot|mastodon|signal|snapchat|redditbot|skypeuripreview|viberbot|linebot|embedly|quora|outbrain|tumblr|duckduckbot|yandexbot|rogerbot|showyoubot|kakaotalk|naverbot|seznambot|mediapartners|adsbot|petalbot|applebot|ia_archiver/i.test( - userAgent - ); + const isBot = + /discordbot|twitterbot|facebookexternalhit|bingbot|googlebot|slurp|whatsapp|pinterest|slackbot|telegrambot|linkedinbot|mastodon|signal|snapchat|redditbot|skypeuripreview|viberbot|linebot|embedly|quora|outbrain|tumblr|duckduckbot|yandexbot|rogerbot|showyoubot|kakaotalk|naverbot|seznambot|mediapartners|adsbot|petalbot|applebot|ia_archiver/i.test( + userAgent + ); const albumId = params.id; if (isBot && albumId) { diff --git a/functions/artist/[id].js b/functions/artist/[id].js index 3179d80..1c62591 100644 --- a/functions/artist/[id].js +++ b/functions/artist/[id].js @@ -135,9 +135,10 @@ class ServerAPI { export async function onRequest(context) { const { request, params, env } = context; const userAgent = request.headers.get('User-Agent') || ''; - const isBot = /discordbot|twitterbot|facebookexternalhit|bingbot|googlebot|slurp|whatsapp|pinterest|slackbot|telegrambot|linkedinbot|mastodon|signal|snapchat|redditbot|skypeuripreview|viberbot|linebot|embedly|quora|outbrain|tumblr|duckduckbot|yandexbot|rogerbot|showyoubot|kakaotalk|naverbot|seznambot|mediapartners|adsbot|petalbot|applebot|ia_archiver/i.test( - userAgent - ); + const isBot = + /discordbot|twitterbot|facebookexternalhit|bingbot|googlebot|slurp|whatsapp|pinterest|slackbot|telegrambot|linkedinbot|mastodon|signal|snapchat|redditbot|skypeuripreview|viberbot|linebot|embedly|quora|outbrain|tumblr|duckduckbot|yandexbot|rogerbot|showyoubot|kakaotalk|naverbot|seznambot|mediapartners|adsbot|petalbot|applebot|ia_archiver/i.test( + userAgent + ); const artistId = params.id; if (isBot && artistId) { diff --git a/functions/playlist/[id].js b/functions/playlist/[id].js index 9f96053..15fe6f6 100644 --- a/functions/playlist/[id].js +++ b/functions/playlist/[id].js @@ -136,9 +136,10 @@ class ServerAPI { export async function onRequest(context) { const { request, params, env } = context; const userAgent = request.headers.get('User-Agent') || ''; - const isBot = /discordbot|twitterbot|facebookexternalhit|bingbot|googlebot|slurp|whatsapp|pinterest|slackbot|telegrambot|linkedinbot|mastodon|signal|snapchat|redditbot|skypeuripreview|viberbot|linebot|embedly|quora|outbrain|tumblr|duckduckbot|yandexbot|rogerbot|showyoubot|kakaotalk|naverbot|seznambot|mediapartners|adsbot|petalbot|applebot|ia_archiver/i.test( - userAgent - ); + const isBot = + /discordbot|twitterbot|facebookexternalhit|bingbot|googlebot|slurp|whatsapp|pinterest|slackbot|telegrambot|linkedinbot|mastodon|signal|snapchat|redditbot|skypeuripreview|viberbot|linebot|embedly|quora|outbrain|tumblr|duckduckbot|yandexbot|rogerbot|showyoubot|kakaotalk|naverbot|seznambot|mediapartners|adsbot|petalbot|applebot|ia_archiver/i.test( + userAgent + ); const playlistId = params.id; if (isBot && playlistId) { diff --git a/functions/podcasts/[id].js b/functions/podcasts/[id].js index 4255018..25586fe 100644 --- a/functions/podcasts/[id].js +++ b/functions/podcasts/[id].js @@ -27,9 +27,10 @@ async function getAuthHeaders() { export async function onRequest(context) { const { request, params, env } = context; const userAgent = request.headers.get('User-Agent') || ''; - const isBot = /discordbot|twitterbot|facebookexternalhit|bingbot|googlebot|slurp|whatsapp|pinterest|slackbot|telegrambot|linkedinbot|mastodon|signal|snapchat|redditbot|skypeuripreview|viberbot|linebot|embedly|quora|outbrain|tumblr|duckduckbot|yandexbot|rogerbot|showyoubot|kakaotalk|naverbot|seznambot|mediapartners|adsbot|petalbot|applebot|ia_archiver/i.test( - userAgent - ); + const isBot = + /discordbot|twitterbot|facebookexternalhit|bingbot|googlebot|slurp|whatsapp|pinterest|slackbot|telegrambot|linkedinbot|mastodon|signal|snapchat|redditbot|skypeuripreview|viberbot|linebot|embedly|quora|outbrain|tumblr|duckduckbot|yandexbot|rogerbot|showyoubot|kakaotalk|naverbot|seznambot|mediapartners|adsbot|petalbot|applebot|ia_archiver/i.test( + userAgent + ); const podcastId = params.id; if (isBot && podcastId) { diff --git a/functions/track/[id].js b/functions/track/[id].js index 033a936..cf50d44 100644 --- a/functions/track/[id].js +++ b/functions/track/[id].js @@ -165,9 +165,10 @@ class ServerAPI { export async function onRequest(context) { const { request, params, env } = context; const userAgent = request.headers.get('User-Agent') || ''; - const isBot = /discordbot|twitterbot|facebookexternalhit|bingbot|googlebot|slurp|whatsapp|pinterest|slackbot|telegrambot|linkedinbot|mastodon|signal|snapchat|redditbot|skypeuripreview|viberbot|linebot|embedly|quora|outbrain|tumblr|duckduckbot|yandexbot|rogerbot|showyoubot|kakaotalk|naverbot|seznambot|mediapartners|adsbot|petalbot|applebot|ia_archiver/i.test( - userAgent - ); + const isBot = + /discordbot|twitterbot|facebookexternalhit|bingbot|googlebot|slurp|whatsapp|pinterest|slackbot|telegrambot|linkedinbot|mastodon|signal|snapchat|redditbot|skypeuripreview|viberbot|linebot|embedly|quora|outbrain|tumblr|duckduckbot|yandexbot|rogerbot|showyoubot|kakaotalk|naverbot|seznambot|mediapartners|adsbot|petalbot|applebot|ia_archiver/i.test( + userAgent + ); const trackId = params.id; if (isBot && trackId) { diff --git a/functions/user/@[username].js b/functions/user/@[username].js index 32a0526..a603acf 100644 --- a/functions/user/@[username].js +++ b/functions/user/@[username].js @@ -3,9 +3,10 @@ export async function onRequest(context) { const { request, params, env } = context; const userAgent = request.headers.get('User-Agent') || ''; - const isBot = /discordbot|twitterbot|facebookexternalhit|bingbot|googlebot|slurp|whatsapp|pinterest|slackbot|telegrambot|linkedinbot|mastodon|signal|snapchat|redditbot|skypeuripreview|viberbot|linebot|embedly|quora|outbrain|tumblr|duckduckbot|yandexbot|rogerbot|showyoubot|kakaotalk|naverbot|seznambot|mediapartners|adsbot|petalbot|applebot|ia_archiver/i.test( - userAgent - ); + const isBot = + /discordbot|twitterbot|facebookexternalhit|bingbot|googlebot|slurp|whatsapp|pinterest|slackbot|telegrambot|linkedinbot|mastodon|signal|snapchat|redditbot|skypeuripreview|viberbot|linebot|embedly|quora|outbrain|tumblr|duckduckbot|yandexbot|rogerbot|showyoubot|kakaotalk|naverbot|seznambot|mediapartners|adsbot|petalbot|applebot|ia_archiver/i.test( + userAgent + ); const username = params.username; if (isBot && username) { diff --git a/functions/userplaylist/[id].js b/functions/userplaylist/[id].js index aa7a880..631b4c9 100644 --- a/functions/userplaylist/[id].js +++ b/functions/userplaylist/[id].js @@ -6,9 +6,10 @@ const PUBLIC_COLLECTION = 'public_playlists'; export async function onRequest(context) { const { request, params, env } = context; const userAgent = request.headers.get('User-Agent') || ''; - const isBot = /discordbot|twitterbot|facebookexternalhit|bingbot|googlebot|slurp|whatsapp|pinterest|slackbot|telegrambot|linkedinbot|mastodon|signal|snapchat|redditbot|skypeuripreview|viberbot|linebot|embedly|quora|outbrain|tumblr|duckduckbot|yandexbot|rogerbot|showyoubot|kakaotalk|naverbot|seznambot|mediapartners|adsbot|petalbot|applebot|ia_archiver/i.test( - userAgent - ); + const isBot = + /discordbot|twitterbot|facebookexternalhit|bingbot|googlebot|slurp|whatsapp|pinterest|slackbot|telegrambot|linkedinbot|mastodon|signal|snapchat|redditbot|skypeuripreview|viberbot|linebot|embedly|quora|outbrain|tumblr|duckduckbot|yandexbot|rogerbot|showyoubot|kakaotalk|naverbot|seznambot|mediapartners|adsbot|petalbot|applebot|ia_archiver/i.test( + userAgent + ); const playlistId = params.id; if (isBot && playlistId) { @@ -30,7 +31,11 @@ export async function onRequest(context) { extraData = {}; } - const title = record.title || record.name || (extraData && (extraData.title || extraData.name)) || 'Untitled Playlist'; + const title = + record.title || + record.name || + (extraData && (extraData.title || extraData.name)) || + 'Untitled Playlist'; let tracks = []; try {