personal web client for Bluesky
typescript
solidjs
bluesky
atcute
1import type {
2 AppBskyEmbedExternal,
3 AppBskyEmbedImages,
4 AppBskyEmbedRecord,
5 AppBskyFeedDefs,
6 AppBskyFeedPost,
7} from '@atcute/bluesky';
8import type { $type } from '@atcute/lexicons';
9
10type RecordEmbed = AppBskyFeedPost.Main['embed'];
11type ViewEmbed = AppBskyFeedDefs.PostView['embed'];
12
13export const unwrapPostEmbedText = (embed: RecordEmbed | ViewEmbed): string => {
14 let str = '';
15
16 const media = getMediaEmbed(embed);
17
18 if (media) {
19 const type = media.$type;
20
21 if (type === 'app.bsky.embed.external' || type === 'app.bsky.embed.external#view') {
22 str += ` ` + media.external.title;
23 } else if (type === 'app.bsky.embed.images' || type === 'app.bsky.embed.images#view') {
24 const images = media.images;
25
26 for (let idx = 0, len = images.length; idx < len; idx++) {
27 str += ` ` + images[idx].alt;
28 }
29 }
30 }
31
32 return str;
33};
34
35type RecordMedia = AppBskyEmbedExternal.Main | AppBskyEmbedImages.Main;
36type ViewMedia = AppBskyEmbedExternal.View | AppBskyEmbedImages.View;
37
38const getMediaEmbed = (
39 embed: RecordEmbed | ViewEmbed,
40): $type.enforce<RecordMedia | ViewMedia> | undefined => {
41 if (embed) {
42 const type = embed.$type;
43
44 if (
45 type === 'app.bsky.embed.external' ||
46 type === 'app.bsky.embed.external#view' ||
47 type === 'app.bsky.embed.images' ||
48 type === 'app.bsky.embed.images#view'
49 ) {
50 return embed;
51 } else if (type === 'app.bsky.embed.recordWithMedia' || type === 'app.bsky.embed.recordWithMedia#view') {
52 const media = embed.media;
53 const mediatype = media.$type;
54
55 if (
56 mediatype === 'app.bsky.embed.external' ||
57 mediatype === 'app.bsky.embed.external#view' ||
58 mediatype === 'app.bsky.embed.images' ||
59 mediatype === 'app.bsky.embed.images#view'
60 ) {
61 return media;
62 }
63 }
64 }
65};
66
67export const getEmbeddedPost = (
68 embed: AppBskyFeedDefs.PostView['embed'],
69): AppBskyEmbedRecord.ViewRecord | undefined => {
70 if (embed) {
71 if (embed.$type === 'app.bsky.embed.record#view') {
72 if (embed.record.$type === 'app.bsky.embed.record#viewRecord') {
73 return embed.record;
74 }
75 } else if (embed.$type === 'app.bsky.embed.recordWithMedia#view') {
76 if (embed.record.record.$type === 'app.bsky.embed.record#viewRecord') {
77 return embed.record.record;
78 }
79 }
80 }
81};
82
83export const embedViewRecordToPostView = (
84 v: AppBskyEmbedRecord.ViewRecord,
85): AppBskyFeedDefs.PostView & { $transform: true } => {
86 return {
87 $transform: true,
88 uri: v.uri,
89 cid: v.cid,
90 author: v.author,
91 record: v.value,
92 indexedAt: v.indexedAt,
93 labels: v.labels,
94 embed: v.embeds?.[0],
95 likeCount: v.likeCount,
96 replyCount: v.replyCount,
97 repostCount: v.repostCount,
98 quoteCount: v.quoteCount,
99 };
100};