Merge branch 'main' into fix/ui-ux-video-library-fullscreen
This commit is contained in:
commit
6ace8e19be
12 changed files with 279 additions and 97 deletions
46
INSTANCES.md
46
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) |
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -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,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/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) {
|
||||
|
|
|
|||
|
|
@ -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/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) {
|
||||
|
|
|
|||
|
|
@ -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,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/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) {
|
||||
|
|
|
|||
99
functions/podcasts/[id].js
Normal file
99
functions/podcasts/[id].js
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
// 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 = `
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>${title}</title>
|
||||
<meta name="description" content="${description}">
|
||||
<meta name="theme-color" content="#000000">
|
||||
|
||||
<meta property="og:site_name" content="Monochrome">
|
||||
<meta property="og:title" content="${title}">
|
||||
<meta property="og:description" content="${description}">
|
||||
<meta property="og:image" content="${imageUrl}">
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:url" content="${pageUrl}">
|
||||
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:title" content="${title}">
|
||||
<meta name="twitter:description" content="${description}">
|
||||
<meta name="twitter:image" content="${imageUrl}">
|
||||
</head>
|
||||
<body>
|
||||
<h1>${title}</h1>
|
||||
<p>${description}</p>
|
||||
<img src="${imageUrl}" alt="Podcast Cover">
|
||||
</body>
|
||||
</html>
|
||||
`;
|
||||
|
||||
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));
|
||||
}
|
||||
|
|
@ -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/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) {
|
||||
|
|
|
|||
|
|
@ -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/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) {
|
||||
|
|
|
|||
116
functions/userplaylist/[id].js
Normal file
116
functions/userplaylist/[id].js
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
// 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 = `
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>${title}</title>
|
||||
<meta name="description" content="${description}">
|
||||
<meta name="theme-color" content="#000000">
|
||||
|
||||
<meta property="og:site_name" content="Monochrome">
|
||||
<meta property="og:title" content="${title}">
|
||||
<meta property="og:description" content="${description}">
|
||||
<meta property="og:image" content="${imageUrl}">
|
||||
<meta property="og:type" content="music.playlist">
|
||||
<meta property="og:url" content="${pageUrl}">
|
||||
<meta property="music:song_count" content="${trackCount}">
|
||||
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:title" content="${title}">
|
||||
<meta name="twitter:description" content="${description}">
|
||||
<meta name="twitter:image" content="${imageUrl}">
|
||||
</head>
|
||||
<body>
|
||||
<h1>${title}</h1>
|
||||
<p>${description}</p>
|
||||
<img src="${imageUrl}" alt="Playlist Cover">
|
||||
</body>
|
||||
</html>
|
||||
`;
|
||||
|
||||
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));
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -2731,15 +2731,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();
|
||||
|
|
|
|||
|
|
@ -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() },
|
||||
];
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue