diff --git a/mods/features/adblock.js b/mods/features/adblock.js index d9959264..06720011 100644 --- a/mods/features/adblock.js +++ b/mods/features/adblock.js @@ -341,24 +341,27 @@ function deArrowify(items) { } } - function hqify(items) { for (const item of items) { if (!item.tileRenderer) continue; if (item.tileRenderer.style !== 'TILE_STYLE_YTLR_DEFAULT') continue; - if (configRead('enableHqThumbnails')) { - if (!item.tileRenderer.onSelectCommand?.watchEndpoint?.videoId) continue; - if (!item.tileRenderer.header?.tileHeaderRenderer?.thumbnail?.thumbnails?.[0]?.url) continue; - const videoID = item.tileRenderer.onSelectCommand.watchEndpoint.videoId; - const queryArgs = item.tileRenderer.header.tileHeaderRenderer.thumbnail.thumbnails[0].url.split('?')[1]; - item.tileRenderer.header.tileHeaderRenderer.thumbnail.thumbnails = [ - { - url: `https://i.ytimg.com/vi/${videoID}/sddefault.jpg${queryArgs ? `?${queryArgs}` : ''}`, - width: 640, - height: 480 - } - ]; - } + if (!configRead('enableHqThumbnails')) continue; + const videoID = item.tileRenderer.onSelectCommand?.watchEndpoint?.videoId; + if (!videoID) continue; + // Guard: some home page tiles have no thumbnail yet (lazy-loaded) — skip rather than crash. + const existingUrl = item.tileRenderer.header?.tileHeaderRenderer?.thumbnail?.thumbnails?.[0]?.url; + if (!existingUrl) continue; + // Do NOT carry over query args: the original `sqp` param is a signed token tied to the + // original filename — reusing it on a different filename causes a CDN signature mismatch + // and YouTube returns the grey "not available" placeholder instead of the real thumbnail. + // Start with hqdefault (guaranteed for every video), then async-upgrade to + // sddefault (640x480) if it exists on the CDN. On a TV the JSON parse → + // layout pipeline is slow enough that the HEAD usually resolves in time. + const thumbs = item.tileRenderer.header.tileHeaderRenderer.thumbnail.thumbnails; + thumbs[0] = { url: `https://i.ytimg.com/vi/${videoID}/hqdefault.jpg`, width: 480, height: 360 }; + fetch(`https://i.ytimg.com/vi/${videoID}/sddefault.jpg`, { method: 'HEAD' }) + .then(res => { if (res.ok) thumbs[0] = { url: `https://i.ytimg.com/vi/${videoID}/sddefault.jpg`, width: 640, height: 480 }; }) + .catch(() => {}); } }