pleroma-like client for Bluesky
pl.hexmani.ac
bluesky
pleroma
social-media
1import RelativeTime from "@yaireo/relative-time";
2import { Show } from "solid-js";
3import type { Post } from "../types/post";
4
5type PostProps = {
6 data: Post;
7};
8
9// todo: don't just copy FA svgs in from akko-fe
10const BoostIcon = () => {
11 return (
12 <svg role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512">
13 <title>Boost</title>
14 <path
15 class=""
16 fill="#5dc94a"
17 d="M272 416c17.7 0 32-14.3 32-32s-14.3-32-32-32H160c-17.7 0-32-14.3-32-32V192h32c12.9 0 24.6-7.8 29.6-19.8s2.2-25.7-6.9-34.9l-64-64c-12.5-12.5-32.8-12.5-45.3 0l-64 64c-9.2 9.2-11.9 22.9-6.9 34.9s16.6 19.8 29.6 19.8l32 0 0 128c0 53 43 96 96 96H272zM304 96c-17.7 0-32 14.3-32 32s14.3 32 32 32l112 0c17.7 0 32 14.3 32 32l0 128H416c-12.9 0-24.6 7.8-29.6 19.8s-2.2 25.7 6.9 34.9l64 64c12.5 12.5 32.8 12.5 45.3 0l64-64c9.2-9.2 11.9-22.9 6.9-34.9s-16.6-19.8-29.6-19.8l-32 0V192c0-53-43-96-96-96L304 96z"
18 ></path>
19 </svg>
20 );
21};
22
23const Post = (props: PostProps) => {
24 return (
25 <div class="post">
26 <Show when={props.data.context}>
27 <div class="post-context">
28 <img
29 src={props.data.context?.invoker.avatar}
30 alt={`Profile picture of ${props.data.context?.invoker.handle}`}
31 />
32 <span class="post-context-user">
33 {props.data.context?.invoker.displayName}
34 </span>
35 <BoostIcon />
36 <span>reposted</span>
37 </div>
38 </Show>
39 <div class="post-content">
40 <img
41 class="post-avatar"
42 src={props.data.avatar}
43 alt={`Profile picture of ${props.data.handle}`}
44 />
45 <div class="post-main">
46 <div class="post-header">
47 <div class="post-author">
48 <span>{props.data.displayName}</span>
49 <span class="post-author-handle">@{props.data.handle}</span>
50 </div>
51 <span class="post-time">
52 {new RelativeTime({ options: { style: "narrow" } }).from(
53 props.data.createdAt,
54 )}
55 </span>
56 </div>
57 <div class="post-body">{props.data.record.text}</div>
58 </div>
59 </div>
60 <div class="post-interactions">
61 <p>
62 {props.data.counts.replyCount}{" "}
63 {props.data.counts.replyCount === 1 ? "reply" : "replies"} |{" "}
64 {props.data.counts.repostCount}{" "}
65 {props.data.counts.repostCount === 1 ? "repost" : "reposts"} |{" "}
66 {props.data.counts.likeCount}{" "}
67 {props.data.counts.likeCount === 1 ? "like" : "likes"}
68 </p>
69 </div>
70 </div>
71 );
72};
73
74export default Post;