feat(embeds): interactive X/Twitter post embed + Apple Music player
CI / Build & Quality Checks (push) Successful in 10m39s
CI / Trigger Desktop Build (push) Successful in 7s

X/Twitter: the static OG card was a snapshot — no video, no galleries/threads.
Keep it as the (reliable) facade and add a 'View post' button that loads the
official platform.twitter.com interactive embed on click: playable video/GIF,
image galleries, quote tweets. The embed self-sizes via a scoped postMessage
resize listener (matched to our iframe + the platform.twitter.com origin). Nothing
loads from X until the user clicks, and the link still works if X blocks the frame.

Apple Music: music.apple.com album/playlist/song links now play inline via the
embed.music.apple.com player (compact for a single song, tall for collections),
through the existing MediaEmbedCard audio path.

Pure parsers/builders unit-tested (13 cases). Desktop CSP frame-src adds
platform.twitter.com + embed.music.apple.com (separate commit).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-06 20:14:53 -04:00
parent 6c903fe3e5
commit 791b1cb5ea
4 changed files with 198 additions and 27 deletions
+27
View File
@@ -11,6 +11,8 @@ import {
getTwitchTarget,
getSpotifyEmbedTarget,
isSoundCloudTrack,
getAppleMusicEmbed,
getTweetId,
buildVideoEmbedUrl,
spotifyEmbedHeight,
parseMediaEmbed,
@@ -109,6 +111,31 @@ test('parseMediaEmbed: routes provider + kind, builds embed URLs', () => {
assert.equal(parseMediaEmbed('https://example.com/x', HOST), null);
});
test('Apple Music: album vs single song height, embed host swap', () => {
const album = getAppleMusicEmbed('https://music.apple.com/us/album/some-album/123456');
assert.equal(album?.embedUrl, 'https://embed.music.apple.com/us/album/some-album/123456');
assert.equal(album?.height, 450);
const song = getAppleMusicEmbed('https://music.apple.com/us/album/some-album/123456?i=789');
assert.equal(song?.height, 175);
assert.ok(song?.embedUrl.includes('?i=789'));
assert.equal(getAppleMusicEmbed('https://music.apple.com/us/browse'), null);
assert.equal(getAppleMusicEmbed('https://example.com/album/x/1'), null);
});
test('getTweetId', () => {
assert.equal(getTweetId('https://x.com/user/status/1799999999999999999'), '1799999999999999999');
assert.equal(getTweetId('https://twitter.com/user/status/12345'), '12345');
assert.equal(getTweetId('https://x.com/user'), null);
assert.equal(getTweetId('https://youtube.com/watch?v=x'), null);
});
test('parseMediaEmbed: Apple Music → audio', () => {
const m = parseMediaEmbed('https://music.apple.com/us/album/x/1?i=2', 'chat.lotusguild.org');
assert.equal(m?.provider, 'applemusic');
assert.equal(m?.kind, 'audio');
assert.equal(m?.height, 175);
});
test('parseMediaEmbed: Twitch embed carries the parent host', () => {
const chan = parseMediaEmbed('https://twitch.tv/streamer', HOST);
assert.equal(chan?.provider, 'twitch');