Preserve embedded original posts when rendering swarm reposts

Hop-State: A_06FPEZ3WB9ZANP4K6YVY4S0
Hop-Proposal: R_06FPEZ34Y13T1DBP9HTRMBR
Hop-Task: T_06FPEYF7BR1M5HZ8Z1684KG
Hop-Attempt: AT_06FPEYF7BS5KHWEJRTK2PW0
This commit is contained in:
2026-07-15 13:33:59 -07:00
committed by Hop
parent 7143f6cfd7
commit 1b9857b427
4 changed files with 142 additions and 95 deletions
+82
View File
@@ -0,0 +1,82 @@
import { describe, expect, it } from 'vitest';
import type { SwarmPost } from '@/app/api/swarm/timeline/route';
import { mapSwarmPostToPost } from './feed-post';
const original: SwarmPost = {
id: 'original-id',
content: 'Original post body',
createdAt: '2026-07-15T18:49:15.000Z',
author: {
handle: 'original-author',
displayName: 'Original Author',
avatarUrl: 'https://example.com/original.png',
isNsfw: false,
},
nodeDomain: 'remote.example',
nodeIsNsfw: true,
isNsfw: false,
likeCount: 2,
repostCount: 1,
replyCount: 0,
media: [{ url: 'https://example.com/image.jpg', mimeType: 'image/jpeg' }],
};
describe('mapSwarmPostToPost', () => {
it('preserves the complete embedded original when mapping a repost', () => {
const repost: SwarmPost = {
id: 'repost-id',
content: '',
createdAt: '2026-07-15T20:07:48.000Z',
repostOfId: original.id,
repostOf: original,
author: {
handle: 'reposter',
displayName: 'Reposter',
isNsfw: false,
},
nodeDomain: 'remote.example',
nodeIsNsfw: true,
isNsfw: false,
likeCount: 0,
repostCount: 0,
replyCount: 0,
};
const mapped = mapSwarmPostToPost(repost);
expect(mapped.repostOfId).toBe('swarm:remote.example:original-id');
expect(mapped.repostOf).toMatchObject({
id: 'swarm:remote.example:original-id',
content: 'Original post body',
nodeDomain: 'remote.example',
author: {
handle: 'original-author',
nodeIsNsfw: true,
},
media: [{
id: 'swarm:remote.example:original-id:media:0',
url: 'https://example.com/image.jpg',
mimeType: 'image/jpeg',
}],
});
});
it('preserves interaction and link-preview fields', () => {
const mapped = mapSwarmPostToPost({
...original,
isLiked: true,
isReposted: true,
linkPreviewUrl: 'https://example.com/story',
linkPreviewTitle: 'Story',
linkPreviewType: 'card',
});
expect(mapped).toMatchObject({
isLiked: true,
isReposted: true,
linkPreviewUrl: 'https://example.com/story',
linkPreviewTitle: 'Story',
linkPreviewType: 'card',
});
});
});
+55
View File
@@ -0,0 +1,55 @@
import type { SwarmPost } from '@/app/api/swarm/timeline/route';
import type { Post } from '@/lib/types';
export type InteractiveSwarmPost = SwarmPost & {
isLiked?: boolean;
isReposted?: boolean;
};
export function mapSwarmPostToPost(post: InteractiveSwarmPost): Post {
const normalizedId = `swarm:${post.nodeDomain}:${post.id}`;
return {
id: normalizedId,
originalPostId: post.id,
content: post.content,
createdAt: post.createdAt,
likesCount: post.likeCount,
repostsCount: post.repostCount,
repliesCount: post.replyCount,
isSwarm: true,
nodeDomain: post.nodeDomain,
repostOfId: post.repostOfId
? `swarm:${post.nodeDomain}:${post.repostOfId}`
: null,
repostOf: post.repostOf
? mapSwarmPostToPost(post.repostOf as InteractiveSwarmPost)
: null,
author: {
id: `swarm:${post.nodeDomain}:${post.author.handle}`,
handle: post.author.handle,
displayName: post.author.displayName,
avatarUrl: post.author.avatarUrl,
isSwarm: true,
isBot: post.author.isBot,
isNsfw: post.author.isNsfw,
nodeIsNsfw: post.nodeIsNsfw,
nodeDomain: post.nodeDomain,
},
media: post.media?.map((item, index) => ({
id: `${normalizedId}:media:${index}`,
url: item.url,
altText: item.altText || null,
mimeType: item.mimeType || null,
})) || [],
linkPreviewUrl: post.linkPreviewUrl || null,
linkPreviewTitle: post.linkPreviewTitle || null,
linkPreviewDescription: post.linkPreviewDescription || null,
linkPreviewImage: post.linkPreviewImage || null,
linkPreviewType: post.linkPreviewType || null,
linkPreviewVideoUrl: post.linkPreviewVideoUrl || null,
linkPreviewMedia: post.linkPreviewMedia || null,
isLiked: post.isLiked || false,
isReposted: post.isReposted || false,
};
}