Skip to content

Commit

Permalink
fix quote posts when an image is attached
Browse files Browse the repository at this point in the history
  • Loading branch information
videah committed Jan 16, 2024
1 parent ecf15c1 commit 94370ec
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 29 deletions.
6 changes: 4 additions & 2 deletions lib/models/mastodon/mastodon_card.dart
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ class MastodonCard {

var title = 'Quote Post';
var handle = '@unknown.bsky.social';
var description = '';
var clickableUrl = base;

// Ivory expects an image to render a card so we pass a 1x1 transparent
Expand All @@ -91,6 +92,7 @@ class MastodonCard {
record: (post) {
handle = post.data.author.handle;
title = 'Quote Post - (@$handle) \n ${post.data.value.text}';
description = post.data.value.text;
clickableUrl = 'https://$base/@$handle/${dbRecord.id}';

// If the record has a media attachment, we can use that instead.
Expand Down Expand Up @@ -120,9 +122,9 @@ class MastodonCard {
return MastodonCard(
url: clickableUrl,
title: title,
description: '',
description: description,
type: CardType.link,
authorName: '',
authorName: handle,
authorUrl: '',
providerName: '',
providerUrl: '',
Expand Down
5 changes: 2 additions & 3 deletions lib/models/mastodon/mastodon_media_attachment.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,14 @@ class MastodonMediaAttachment {
/// Converts a [bsky.EmbedViewImagesView] to a [MastodonMediaAttachment].
factory MastodonMediaAttachment.fromEmbed(
bsky.EmbedViewImagesView embed,
bsky.Image? image,
) {
// If embed.alt is empty, we return null instead.
final description = embed.alt.isEmpty ? null : embed.alt;

final meta = MediaAttachmentMetadata(
original: Metadata(
width: image?.aspectRatio?.width ?? 1,
height: image?.aspectRatio?.height ?? 1,
width: embed.aspectRatio?.width ?? 1,
height: embed.aspectRatio?.height ?? 1,
),
);

Expand Down
81 changes: 57 additions & 24 deletions lib/models/mastodon/mastodon_post.dart
Original file line number Diff line number Diff line change
Expand Up @@ -98,19 +98,25 @@ class MastodonPost {
if (embed != null) {
if (embed.data is bsky.EmbedViewImages) {
final embedded = embed.data as bsky.EmbedViewImages;
final embeddedImages = post.record.embed!.data as bsky.EmbedImages;

// Loop through both lists and match both based on index.
for (var i = 0; i < embedded.images.length; i++) {
final imageView = embedded.images[i];
final imageData = embeddedImages.images[i];

final attachment = MastodonMediaAttachment.fromEmbed(
imageView,
imageData,
);
// Add the images to the list of media attachments.
for (final image in embedded.images) {
final attachment = MastodonMediaAttachment.fromEmbed(image);
mediaAttachments.add(attachment);
}
} else if (embed.data is bsky.EmbedViewRecordWithMedia) {
final embedded = embed.data as bsky.EmbedViewRecordWithMedia;

// When there are other types of embeds, we need to grab the
// images with EmbedViewRecordWithMedia.
embedded.media.mapOrNull(
images: (media) {
for (final image in media.data.images) {
final attachment = MastodonMediaAttachment.fromEmbed(image);
mediaAttachments.add(attachment);
}
},
);
}
}

Expand Down Expand Up @@ -139,16 +145,26 @@ class MastodonPost {
const base = 'https://bsky.app';
final url = '$base/profile/${account.username}/post/$postId';

final card = await MastodonCard.fromEmbed(post.embed);
var card = await MastodonCard.fromEmbed(post.embed);

// If there is a card but no link to it in the content, add it.
if (card != null) {
if (!text.contains(card.url)) {
content +=
' <a href="${card.url}" rel="nofollow noopener noreferrer" target="_blank">${card.url}</a>';
'\n\n<a href="${card.url}" rel="nofollow noopener noreferrer" target="_blank">${mediaAttachments.isEmpty ? card.url : 'View Quote Post ⤵'}</a>';

if (mediaAttachments.isNotEmpty) {
content += '<p>"${card.description}" — @${card.authorName}</p>';
}
}
}

// If there's an image attached to the post we drop the card and instead
// include a link to the card url in the post content.
if (mediaAttachments.isNotEmpty) {
card = null;
}

final baseUrl = env.getOrElse(
'SKYBRIDGE_BASEURL',
() => throw Exception('SKYBRIDGE_BASEURL not set!'),
Expand Down Expand Up @@ -206,23 +222,30 @@ class MastodonPost {
final mediaAttachments = <MastodonMediaAttachment>[];
final account = await MastodonAccount.fromActor(post.author.toActor());

// Handle embedded content.
final embed = post.embed;
if (embed != null) {
if (embed.data is bsky.EmbedViewImages) {
final embedded = embed.data as bsky.EmbedViewImages;
final embeddedImages = post.record.embed!.data as bsky.EmbedImages;

// Loop through both lists and match both based on index.
for (var i = 0; i < embedded.images.length; i++) {
final imageView = embedded.images[i];
final imageData = embeddedImages.images[i];

final attachment = MastodonMediaAttachment.fromEmbed(
imageView,
imageData,
);
// Add the images to the list of media attachments.
for (final image in embedded.images) {
final attachment = MastodonMediaAttachment.fromEmbed(image);
mediaAttachments.add(attachment);
}
} else if (embed.data is bsky.EmbedViewRecordWithMedia) {
final embedded = embed.data as bsky.EmbedViewRecordWithMedia;

// When there are other types of embeds, we need to grab the
// images with EmbedViewRecordWithMedia.
embedded.media.mapOrNull(
images: (media) {
for (final image in media.data.images) {
final attachment = MastodonMediaAttachment.fromEmbed(image);
mediaAttachments.add(attachment);
}
},
);
}
}

Expand All @@ -241,16 +264,26 @@ class MastodonPost {
var content = processed.htmlText;
final text = post.record.text;

final card = await MastodonCard.fromEmbed(post.embed);
var card = await MastodonCard.fromEmbed(post.embed);

// If there is a card but no link to it in the content, add it.
if (card != null) {
if (!text.contains(card.url)) {
content +=
' <a href="${card.url}" rel="nofollow noopener noreferrer" target="_blank">${card.url}</a>';
'\n\n<a href="${card.url}" rel="nofollow noopener noreferrer" target="_blank">${mediaAttachments.isEmpty ? card.url : 'View Quote Post ⤵'}</a>';

if (mediaAttachments.isNotEmpty) {
content += '<p>"${card.description}" — @${card.authorName}</p>';
}
}
}

// If there's an image attached to the post we drop the card and instead
// include a link to the card url in the post content.
if (mediaAttachments.isNotEmpty) {
card = null;
}

final baseUrl = env.getOrElse(
'SKYBRIDGE_BASEURL',
() => throw Exception('SKYBRIDGE_BASEURL not set!'),
Expand Down

0 comments on commit 94370ec

Please sign in to comment.