fix(embed): restore youtube thumbnails and file-row labels (#1148)

* fix(comment-content): render reason text as comment content

* fix(post-form): use native browser styling for flash tag select

Exclude the flash tag dropdown from themed post-form select styling so it
renders with the browser's default select appearance, matching the flag selector.

* fix(p2p-stats): show peer flags for DNS6 relay hostnames

Extract embedded IPv6 addresses from dns6 multiaddrs so geo lookup and country flags work for relay peers that publish IPv6 via DNS hostnames.

* fix(flags): hide geolocation-only selectors on /int/ and /sp/

Country-only boards auto-publish geographic location flags without
showing a flag dropdown, matching existing /bant/ behavior.

* fix(embed): restore youtube thumbnails and file-row labels

Restore thumbnail-first previews for YouTube embeds in post media and markdown hover.
Desktop posts show File with the thumbnail image URL and a youtube video type label.

* fix(embed): address youtube thumbnail review feedback

Translate the youtube video label, handle mobile/music YouTube hosts as standard YouTube URLs, keep affected mocks current, and cap default Vitest workers to reduce local CPU spikes.
This commit is contained in:
Tommaso Casaburi
2026-06-01 12:57:17 +07:00
committed by GitHub
parent d48cf10ee8
commit 829b672053
57 changed files with 482 additions and 127 deletions
+31
View File
@@ -1,3 +1,5 @@
const STANDARD_YOUTUBE_HOSTS = new Set<string>(['youtube.com', 'www.youtube.com', 'm.youtube.com', 'music.youtube.com', 'youtu.be', 'www.youtu.be']);
export const youtubeHosts = new Set<string>([
'youtube.com',
'www.youtube.com',
@@ -46,6 +48,35 @@ const canEmbedHosts = new Set<string>([
...spotifyHosts,
]);
export const getYouTubeVideoId = (parsedUrl: URL): string | null => {
if (parsedUrl.searchParams.has('list') && !parsedUrl.searchParams.get('v') && !parsedUrl.host.includes('youtu.be') && !parsedUrl.pathname.includes('/shorts/')) {
return null;
}
const videoIdFromQuery = parsedUrl.searchParams.get('v');
if (videoIdFromQuery) {
return videoIdFromQuery;
}
if (parsedUrl.host.includes('youtu.be')) {
return parsedUrl.pathname.slice(1).split('/')[0] || null;
}
if (parsedUrl.pathname.includes('/shorts/')) {
return parsedUrl.pathname.split('/shorts/')[1]?.split('/')[0] || null;
}
const isInvidious = !STANDARD_YOUTUBE_HOSTS.has(parsedUrl.host) && (youtubeHosts.has(parsedUrl.host) || parsedUrl.host.startsWith('yt.'));
if (isInvidious) {
if (parsedUrl.pathname.startsWith('/watch')) {
return parsedUrl.searchParams.get('v');
}
return parsedUrl.pathname.split('/').filter(Boolean).pop() || null;
}
return null;
};
export const canEmbed = (parsedUrl: URL): boolean => {
if (xHosts.has(parsedUrl.host)) {
return Boolean(getXTweetId(parsedUrl));