diff --git a/src/components/Card.vue b/src/components/Card.vue
index f426ed6..797ceed 100644
--- a/src/components/Card.vue
+++ b/src/components/Card.vue
@@ -43,12 +43,15 @@ const onMediaLoad = inject('fixLayout', () => undefined)
-
{
}
// Skip posts that would show up empty
- if (!cfg.showText && !status.media_attachments?.length) return false;
+ if (!cfg.showText && findMedia(status).length == 0) return false;
if (!cfg.showMedia && !status.content.trim()) return false;
// Accept anything else
return true;
}
+function findMedia(status: MastodonStatus) {
+ const media: PostMedia[] = []
+
+ status.media_attachments?.map((m): PostMedia | undefined => {
+ const url = m.url;
+ const alt = m.description ?? undefined
+ const preview = m.preview_url ?? undefined
+ switch (m.type) {
+ case "image":
+ return { type: "image", url, href:url, preview, alt }
+ case "video":
+ case "gifv":
+ return { type: "video", url, href:url, preview, alt }
+ case "audio":
+ case "unknown":
+ return
+ }
+ }).filter(m=>!!m).forEach(m=>media.push(m))
+
+ // Fall back to preview card images if no media is attached (e.g. for peertube posts)
+ if(media.length == 0 && status.card) {
+ const card = status.card
+ if(notBlank(card.image) && notBlank(card.url))
+ media.push({type:"card", url: card.url, preview:card.image, alt: status.card.description})
+ }
+
+ return media
+}
+
/**
* Convert a mastodon status object to a Post.
*/
@@ -282,18 +310,7 @@ const statusToWallPost = (cfg: Config, status: MastodonStatus): Post => {
const profile = status.account.acct
const content = replaceEmojis(status.content, status.emojis)
- const media = status.media_attachments?.map((m): PostMedia | undefined => {
- switch (m.type) {
- case "image":
- return { type: "image", url: m.url, preview: m.preview_url, alt: m.description ?? undefined }
- case "video":
- case "gifv":
- return { type: "video", url: m.url, preview: m.preview_url, alt: m.description ?? undefined }
- case "audio":
- case "unknown":
- return
- }
- }).filter((m): m is PostMedia => m !== undefined)
+ const media = findMedia(status)
return {
id: status.uri,
diff --git a/src/types.ts b/src/types.ts
index a0d083a..89b76c7 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -45,10 +45,11 @@ export type Post = {
};
export type PostMedia = {
- type: "image" | "video"
- url: string,
- preview: string
+ type: "image" | "video" | "card"
+ url: string
+ preview?: string
alt?: string
+ size?: [number,number]
}
@@ -67,6 +68,7 @@ export type MastodonStatus = {
in_reply_to_id?: string | null;
language?: string | null;
media_attachments: Array;
+ card?: MastodonCard,
reblog?: MastodonStatus | null;
sensitive: boolean;
spoiler_text?: string | null;
@@ -114,3 +116,23 @@ export type MastodonMediaAttachment = {
preview_url: string;
url: string;
}
+
+export type MastodonCard = {
+ url: string;
+ title: string;
+ description: string;
+ language: string;
+ type: string;
+ author_name: string;
+ author_url: string;
+ provider_name: string;
+ provider_url: string;
+ html: string;
+ width: number;
+ height: number;
+ image: string;
+ image_description: string;
+ embed_url: string;
+ blurhash: string | null;
+ published_at?: any
+}
\ No newline at end of file
diff --git a/src/utils.ts b/src/utils.ts
index ec5e24a..95f8900 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -9,6 +9,10 @@ export function isString(test: any) {
return typeof test === 'string' || test instanceof String
}
+export function notBlank(test?: string) {
+ return test && test.trim().length > 0
+}
+
export function arrayUnique(array: T[]) {
return array.filter((v, i, a) => a.indexOf(v) === i)
}