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
+35 -4
View File
@@ -20,9 +20,13 @@ vi.mock('@bitsocial/bitsocial-react-hooks/dist/lib/localforage-lru/index.js', ()
},
}));
vi.mock('../../../components/embed', () => ({
canEmbed: (url: URL) => testState.canEmbedHosts.has(url.hostname),
}));
vi.mock('../../../components/embed/embed-utils', async (importOriginal) => {
const actual = await importOriginal<typeof import('../../../components/embed/embed-utils')>();
return {
...actual,
canEmbed: (url: URL) => testState.canEmbedHosts.has(url.hostname),
};
});
vi.mock('@capacitor/core', () => ({
Capacitor: {
@@ -33,7 +37,16 @@ vi.mock('@capacitor/core', () => ({
},
}));
import { fetchWebpageThumbnailIfNeeded, getCommentMediaInfo, getDisplayMediaInfoType, getHasThumbnail, getLinkMediaInfo, getMediaDimensions } from '../media-utils';
import {
fetchWebpageThumbnailIfNeeded,
getCommentMediaInfo,
getDisplayMediaInfoType,
getHasThumbnail,
getLinkMediaInfo,
getMediaDimensions,
getPostMediaTypeLabel,
getYouTubeEmbedPostMediaFileLink,
} from '../media-utils';
const clearMemoizedCache = (fn: unknown) => {
const memoized = fn as { clear?: () => void };
@@ -102,6 +115,18 @@ describe('media-utils', () => {
expect(getDisplayMediaInfoType('unknown', t)).toBe('translated:webpage');
});
it('uses the youtube thumbnail url for post media file links and labels', () => {
const mediaInfo = {
patternThumbnailUrl: 'https://img.youtube.com/vi/abc123/0.jpg',
type: 'iframe',
url: 'https://www.youtube.com/watch?v=abc123',
};
expect(getYouTubeEmbedPostMediaFileLink(mediaInfo)).toBe('https://img.youtube.com/vi/abc123/0.jpg');
expect(getPostMediaTypeLabel(mediaInfo, 'iframe', (key) => key)).toBe('youtube_video');
expect(getYouTubeEmbedPostMediaFileLink({ type: 'iframe', url: 'https://streamable.com/clip123' })).toBeUndefined();
});
it('recognizes which media types expose thumbnails', () => {
expect(getHasThumbnail(undefined, 'https://example.com/file.png')).toBe(false);
expect(getHasThumbnail({ type: 'image', url: 'https://example.com/file.png' }, 'https://example.com/file.png')).toBe(true);
@@ -156,6 +181,12 @@ describe('media-utils', () => {
type: 'iframe',
url: 'https://yt.example/watch?v=yt123',
});
testState.canEmbedHosts = new Set(['yewtu.be']);
expect(getLinkMediaInfo('https://yewtu.be/invidious123')).toEqual({
patternThumbnailUrl: 'https://img.youtube.com/vi/invidious123/0.jpg',
type: 'iframe',
url: 'https://yewtu.be/invidious123',
});
});
it('builds comment media info and strips thumbnails for blacklisted domains', () => {