1
0
mirror of https://github.com/RSS-Bridge/rss-bridge.git synced 2025-08-05 08:07:33 +02:00

[BlueskyBridge] Fix cases for missing reply post context and QoL fix for video loading (#4635)

* added fix for missing reply post context

* qol fix - no preload on videos
This commit is contained in:
mruac
2025-08-04 08:20:12 +09:30
committed by GitHub
parent e241f3dcde
commit c65fbd5543

View File

@@ -330,157 +330,163 @@ class BlueskyBridge extends BridgeAbstract
} }
//reply //reply
if ($replyContext && isset($post['reply']) && !isset($post['reply']['parent']['notFound'])) { if ($replyContext && isset($post['reply']) && isset($post['reply']['parent'])) {
$replyPost = $post['reply']['parent']; $replyPost = $post['reply']['parent'];
$replyPostRecord = $replyPost['record'];
$description .= '<hr/>'; $description .= '<hr/>';
$description .= '<p>'; $description .= '<p>';
$replyPostAuthorDID = $replyPost['author']['did']; if (isset($replyPost['notFound']) && $replyPost['notFound']) { //deleted post
$replyPostAuthorHandle = $replyPost['author']['handle'] !== 'handle.invalid' ? '<i>@' . $replyPost['author']['handle'] . '</i> ' : ''; $description .= 'Replied to post was deleted.';
$replyPostDisplayName = $replyPost['author']['displayName'] ?? ''; } elseif (isset($replyPost['blocked']) && $replyPost['blocked']) { //blocked by quote author
$replyPostDisplayName = e($replyPostDisplayName); $description .= 'Author of replied to post has blocked OP.';
$replyPostUri = self::URI . '/profile/' . $this->fallbackAuthor($replyPost['author'], 'url') . '/post/' . explode('app.bsky.feed.post/', $replyPost['uri'])[1]; } else {
$replyPostRecord = $replyPost['record'];
$replyPostAuthorDID = $replyPost['author']['did'];
$replyPostAuthorHandle = $replyPost['author']['handle'] !== 'handle.invalid' ? '<i>@' . $replyPost['author']['handle'] . '</i> ' : '';
$replyPostDisplayName = $replyPost['author']['displayName'] ?? '';
$replyPostDisplayName = e($replyPostDisplayName);
$replyPostUri = self::URI . '/profile/' . $this->fallbackAuthor($replyPost['author'], 'url') . '/post/' . explode('app.bsky.feed.post/', $replyPost['uri'])[1];
// reply post // reply post
$description .= $this->getPostDescription( $description .= $this->getPostDescription(
$replyPostDisplayName, $replyPostDisplayName,
$replyPostAuthorHandle, $replyPostAuthorHandle,
$replyPostUri, $replyPostUri,
$replyPostRecord, $replyPostRecord,
'reply' 'reply'
); );
if (isset($replyPostRecord['embed']['$type'])) { if (isset($replyPostRecord['embed']['$type'])) {
//post link embed //post link embed
if ($replyPostRecord['embed']['$type'] === 'app.bsky.embed.external') { if ($replyPostRecord['embed']['$type'] === 'app.bsky.embed.external') {
$description .= $this->parseExternal($replyPostRecord['embed']['external'], $replyPostAuthorDID); $description .= $this->parseExternal($replyPostRecord['embed']['external'], $replyPostAuthorDID);
} elseif ( } elseif (
$replyPostRecord['embed']['$type'] === 'app.bsky.embed.recordWithMedia' &&
$replyPostRecord['embed']['media']['$type'] === 'app.bsky.embed.external'
) {
$description .= $this->parseExternal($replyPostRecord['embed']['media']['external'], $replyPostAuthorDID);
}
//post images
if (
$replyPostRecord['embed']['$type'] === 'app.bsky.embed.images' ||
(
$replyPostRecord['embed']['$type'] === 'app.bsky.embed.recordWithMedia' && $replyPostRecord['embed']['$type'] === 'app.bsky.embed.recordWithMedia' &&
$replyPostRecord['embed']['media']['$type'] === 'app.bsky.embed.images' $replyPostRecord['embed']['media']['$type'] === 'app.bsky.embed.external'
) ) {
) { $description .= $this->parseExternal($replyPostRecord['embed']['media']['external'], $replyPostAuthorDID);
$images = $replyPost['embed']['images'] ?? $replyPost['embed']['media']['images']; }
foreach ($images as $image) {
$description .= $this->getPostImageDescription($image); //post images
if (
$replyPostRecord['embed']['$type'] === 'app.bsky.embed.images' ||
(
$replyPostRecord['embed']['$type'] === 'app.bsky.embed.recordWithMedia' &&
$replyPostRecord['embed']['media']['$type'] === 'app.bsky.embed.images'
)
) {
$images = $replyPost['embed']['images'] ?? $replyPost['embed']['media']['images'];
foreach ($images as $image) {
$description .= $this->getPostImageDescription($image);
}
}
//post video
if (
$replyPostRecord['embed']['$type'] === 'app.bsky.embed.video' ||
(
$replyPostRecord['embed']['$type'] === 'app.bsky.embed.recordWithMedia' &&
$replyPostRecord['embed']['media']['$type'] === 'app.bsky.embed.video'
)
) {
$description .= $this->getPostVideoDescription(
$replyPostRecord['embed']['video'] ?? $replyPostRecord['embed']['media']['video'],
$replyPostAuthorDID
);
} }
} }
$description .= '</p>';
//post video //quote post
if ( if (
$replyPostRecord['embed']['$type'] === 'app.bsky.embed.video' || isset($replyPostRecord['embed']) &&
( ($replyPostRecord['embed']['$type'] === 'app.bsky.embed.record' || $replyPostRecord['embed']['$type'] === 'app.bsky.embed.recordWithMedia') &&
$replyPostRecord['embed']['$type'] === 'app.bsky.embed.recordWithMedia' && isset($replyPost['embed']['record'])
$replyPostRecord['embed']['media']['$type'] === 'app.bsky.embed.video'
)
) { ) {
$description .= $this->getPostVideoDescription( $description .= '<p>';
$replyPostRecord['embed']['video'] ?? $replyPostRecord['embed']['media']['video'], $replyQuotedRecord = $replyPost['embed']['record']['record'] ?? $replyPost['embed']['record'];
$replyPostAuthorDID
);
}
}
$description .= '</p>';
//quote post if (isset($replyQuotedRecord['notFound']) && $replyQuotedRecord['notFound']) { //deleted post
if ( $description .= 'Quoted post deleted.';
isset($replyPostRecord['embed']) && } elseif (isset($replyQuotedRecord['detached']) && $replyQuotedRecord['detached']) { //detached quote
($replyPostRecord['embed']['$type'] === 'app.bsky.embed.record' || $replyPostRecord['embed']['$type'] === 'app.bsky.embed.recordWithMedia') && $uri_explode = explode('/', $replyQuotedRecord['uri']);
isset($replyPost['embed']['record']) $uri_reconstructed = self::URI . '/profile/' . $uri_explode[2] . '/post/' . $uri_explode[4];
) { $description .= '<a href="' . $uri_reconstructed . '">Quoted post detached.</a>';
$description .= '<p>'; } elseif (isset($replyQuotedRecord['blocked']) && $replyQuotedRecord['blocked']) { //blocked by quote author
$replyQuotedRecord = $replyPost['embed']['record']['record'] ?? $replyPost['embed']['record']; $description .= 'Author of quoted post has blocked OP.';
} elseif (
($replyQuotedRecord['$type'] ?? '') === 'app.bsky.feed.defs#generatorView' ||
($replyQuotedRecord['$type'] ?? '') === 'app.bsky.graph.defs#listView'
) {
$description .= $this->getListFeedDescription($replyQuotedRecord);
} elseif (
($replyQuotedRecord['$type'] ?? '') === 'app.bsky.graph.starterpack' ||
($replyQuotedRecord['$type'] ?? '') === 'app.bsky.graph.defs#starterPackViewBasic'
) {
$description .= $this->getStarterPackDescription($replyPost['embed']['record']);
} else {
$quotedAuthorDid = $replyQuotedRecord['author']['did'];
$quotedDisplayName = $replyQuotedRecord['author']['displayName'] ?? '';
$quotedDisplayName = e($quotedDisplayName);
$quotedAuthorHandle = $replyQuotedRecord['author']['handle'] !== 'handle.invalid' ? '<i>@' . $replyQuotedRecord['author']['handle'] . '</i>' : '';
if (isset($replyQuotedRecord['notFound']) && $replyQuotedRecord['notFound']) { //deleted post $parts = explode('/', $replyQuotedRecord['uri']);
$description .= 'Quoted post deleted.'; $quotedPostId = end($parts);
} elseif (isset($replyQuotedRecord['detached']) && $replyQuotedRecord['detached']) { //detached quote $quotedPostUri = self::URI . '/profile/' . $this->fallbackAuthor($replyQuotedRecord['author'], 'url') . '/post/' . $quotedPostId;
$uri_explode = explode('/', $replyQuotedRecord['uri']);
$uri_reconstructed = self::URI . '/profile/' . $uri_explode[2] . '/post/' . $uri_explode[4];
$description .= '<a href="' . $uri_reconstructed . '">Quoted post detached.</a>';
} elseif (isset($replyQuotedRecord['blocked']) && $replyQuotedRecord['blocked']) { //blocked by quote author
$description .= 'Author of quoted post has blocked OP.';
} elseif (
($replyQuotedRecord['$type'] ?? '') === 'app.bsky.feed.defs#generatorView' ||
($replyQuotedRecord['$type'] ?? '') === 'app.bsky.graph.defs#listView'
) {
$description .= $this->getListFeedDescription($replyQuotedRecord);
} elseif (
($replyQuotedRecord['$type'] ?? '') === 'app.bsky.graph.starterpack' ||
($replyQuotedRecord['$type'] ?? '') === 'app.bsky.graph.defs#starterPackViewBasic'
) {
$description .= $this->getStarterPackDescription($replyPost['embed']['record']);
} else {
$quotedAuthorDid = $replyQuotedRecord['author']['did'];
$quotedDisplayName = $replyQuotedRecord['author']['displayName'] ?? '';
$quotedDisplayName = e($quotedDisplayName);
$quotedAuthorHandle = $replyQuotedRecord['author']['handle'] !== 'handle.invalid' ? '<i>@' . $replyQuotedRecord['author']['handle'] . '</i>' : '';
$parts = explode('/', $replyQuotedRecord['uri']); //quoted post - post
$quotedPostId = end($parts); $description .= $this->getPostDescription(
$quotedPostUri = self::URI . '/profile/' . $this->fallbackAuthor($replyQuotedRecord['author'], 'url') . '/post/' . $quotedPostId; $quotedDisplayName,
$quotedAuthorHandle,
$quotedPostUri,
$replyQuotedRecord,
'quote'
);
//quoted post - post if (isset($replyQuotedRecord['value']['embed']['$type'])) {
$description .= $this->getPostDescription( //quoted post - post link embed
$quotedDisplayName, if ($replyQuotedRecord['value']['embed']['$type'] === 'app.bsky.embed.external') {
$quotedAuthorHandle, $description .= $this->parseExternal($replyQuotedRecord['value']['embed']['external'], $quotedAuthorDid);
$quotedPostUri, }
$replyQuotedRecord,
'quote'
);
if (isset($replyQuotedRecord['value']['embed']['$type'])) { //quoted post - post video
//quoted post - post link embed if (
if ($replyQuotedRecord['value']['embed']['$type'] === 'app.bsky.embed.external') { $replyQuotedRecord['value']['embed']['$type'] === 'app.bsky.embed.video' ||
$description .= $this->parseExternal($replyQuotedRecord['value']['embed']['external'], $quotedAuthorDid); (
} $replyQuotedRecord['value']['embed']['$type'] === 'app.bsky.embed.recordWithMedia' &&
$replyQuotedRecord['value']['embed']['media']['$type'] === 'app.bsky.embed.video'
)
) {
$description .= $this->getPostVideoDescription(
$replyQuotedRecord['value']['embed']['video'] ?? $replyQuotedRecord['value']['embed']['media']['video'],
$quotedAuthorDid
);
}
//quoted post - post video //quoted post - post images
if ( if (
$replyQuotedRecord['value']['embed']['$type'] === 'app.bsky.embed.video' || $replyQuotedRecord['value']['embed']['$type'] === 'app.bsky.embed.images' ||
( (
$replyQuotedRecord['value']['embed']['$type'] === 'app.bsky.embed.recordWithMedia' && $replyQuotedRecord['value']['embed']['$type'] === 'app.bsky.embed.recordWithMedia' &&
$replyQuotedRecord['value']['embed']['media']['$type'] === 'app.bsky.embed.video' $replyQuotedRecord['value']['embed']['media']['$type'] === 'app.bsky.embed.images'
) )
) { ) {
$description .= $this->getPostVideoDescription( foreach ($replyQuotedRecord['embeds'] as $embed) {
$replyQuotedRecord['value']['embed']['video'] ?? $replyQuotedRecord['value']['embed']['media']['video'], if (
$quotedAuthorDid $embed['$type'] === 'app.bsky.embed.images#view' ||
); ($embed['$type'] === 'app.bsky.embed.recordWithMedia#view' && $embed['media']['$type'] === 'app.bsky.embed.images#view')
} ) {
$images = $embed['images'] ?? $embed['media']['images'];
//quoted post - post images foreach ($images as $image) {
if ( $description .= $this->getPostImageDescription($image);
$replyQuotedRecord['value']['embed']['$type'] === 'app.bsky.embed.images' || }
(
$replyQuotedRecord['value']['embed']['$type'] === 'app.bsky.embed.recordWithMedia' &&
$replyQuotedRecord['value']['embed']['media']['$type'] === 'app.bsky.embed.images'
)
) {
foreach ($replyQuotedRecord['embeds'] as $embed) {
if (
$embed['$type'] === 'app.bsky.embed.images#view' ||
($embed['$type'] === 'app.bsky.embed.recordWithMedia#view' && $embed['media']['$type'] === 'app.bsky.embed.images#view')
) {
$images = $embed['images'] ?? $embed['media']['images'];
foreach ($images as $image) {
$description .= $this->getPostImageDescription($image);
} }
} }
} }
} }
} }
$description .= '</p>';
} }
$description .= '</p>';
} }
} }
@@ -496,7 +502,7 @@ class BlueskyBridge extends BridgeAbstract
$videoMime = $video['mimeType']; $videoMime = $video['mimeType'];
$thumbnail = "poster=\"https://video.bsky.app/watch/$authorDID/$videoCID/thumbnail.jpg\"" ?? ''; $thumbnail = "poster=\"https://video.bsky.app/watch/$authorDID/$videoCID/thumbnail.jpg\"" ?? '';
$videoURL = "https://bsky.social/xrpc/com.atproto.sync.getBlob?did=$authorDID&cid=$videoCID"; $videoURL = "https://bsky.social/xrpc/com.atproto.sync.getBlob?did=$authorDID&cid=$videoCID";
return "<figure><video loop $thumbnail controls src=\"$videoURL\" type=\"$videoMime\"/></figure>"; return "<figure><video loop $thumbnail preload=\"none\" controls src=\"$videoURL\" type=\"$videoMime\"/></figure>";
} }
private function getPostImageDescription(array $image) private function getPostImageDescription(array $image)