feat: add telegram-style resource stream
This commit is contained in:
53
src/components/messageStream/MessageBubble.tsx
Normal file
53
src/components/messageStream/MessageBubble.tsx
Normal file
@@ -0,0 +1,53 @@
|
||||
import type { ComponentType } from "react";
|
||||
import type { Post } from "../../types/post";
|
||||
import { useI18n } from "../../i18n";
|
||||
import { TextBubble } from "./bubbles/TextBubble";
|
||||
import { FileDocBubble } from "./bubbles/FileDocBubble";
|
||||
import { ImageBubble } from "./bubbles/ImageBubble";
|
||||
import { ImageWithTextBubble } from "./bubbles/ImageWithTextBubble";
|
||||
import { AlbumBubble } from "./bubbles/AlbumBubble";
|
||||
import { VideoBubble } from "./bubbles/VideoBubble";
|
||||
import { formatDateTime } from "./utils/formatTime";
|
||||
|
||||
type BubbleComponent = ComponentType<{ post: Post }>;
|
||||
|
||||
export function pickBubble(post: Post): BubbleComponent {
|
||||
const a = post.attachments;
|
||||
if (a.length === 0) return TextBubble;
|
||||
if (a.length >= 2 && a.every((x) => x.kind === "image")) return AlbumBubble;
|
||||
const only = a[0];
|
||||
if (only.kind === "video") return VideoBubble;
|
||||
if (only.kind === "image") {
|
||||
return post.text ? ImageWithTextBubble : ImageBubble;
|
||||
}
|
||||
return FileDocBubble;
|
||||
}
|
||||
|
||||
export function MessageBubble({ post }: { post: Post }) {
|
||||
const { lang } = useI18n();
|
||||
const Bubble = pickBubble(post);
|
||||
const isTextOnly = post.attachments.length === 0;
|
||||
const isVisual = post.attachments.some(
|
||||
(a) => a.kind === "image" || a.kind === "video",
|
||||
);
|
||||
|
||||
return (
|
||||
<article
|
||||
id={`post-${post.id}`}
|
||||
className={`relative self-start rounded-2xl bg-ark-panel text-left shadow-sm ${
|
||||
isVisual
|
||||
? "w-[82vw] max-w-[320px] md:w-[52vw] md:max-w-[420px] lg:w-[46vw] lg:max-w-[520px]"
|
||||
: "inline-block max-w-[92%] md:max-w-[680px]"
|
||||
} ${isTextOnly ? "px-3 py-2" : "p-2"}`}
|
||||
>
|
||||
<Bubble post={post} />
|
||||
<time
|
||||
dateTime={post.publishedAt}
|
||||
className="ml-2 mt-1 inline-block float-right text-[10.5px] leading-none text-neutral-500"
|
||||
>
|
||||
{formatDateTime(post.publishedAt, lang)}
|
||||
</time>
|
||||
<span className="block clear-both" />
|
||||
</article>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user