1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
import type { Tweet } from "react-tweet/api";
import {
type TwitterComponents,
TweetContainer,
TweetInReplyTo,
TweetBody,
TweetMedia,
TweetInfo,
QuotedTweet,
enrichTweet,
EnrichedTweet,
} from "react-tweet";
import clsx from "clsx";
import s from "./tweet-header.module.css";
import { VerifiedBadge } from "./verified-badge";
type Props = {
tweet: Tweet | { error: string };
components?: TwitterComponents;
};
type AvatarImgProps = {
src: string;
alt: string;
width: number;
height: number;
};
const AvatarImg = (props: AvatarImgProps) => <img {...props} />;
const TweetHeader = ({
tweet,
components,
}: {
tweet: EnrichedTweet;
components?: TwitterComponents;
}) => {
const Img = components?.AvatarImg ?? AvatarImg;
const { user } = tweet;
return (
<div className={s.header}>
<a
href={tweet.url}
className={s.avatar}
target="_blank"
rel="noopener noreferrer"
>
<div
className={clsx(
s.avatarOverflow,
user.profile_image_shape === "Square" && s.avatarSquare,
)}
>
<Img
src={user.profile_image_url_https}
alt={user.name}
width={48}
height={48}
/>
</div>
<div className={s.avatarOverflow}>
<div className={s.avatarShadow}></div>
</div>
</a>
<div className={s.author}>
<a
href={tweet.url}
className={s.authorLink}
target="_blank"
rel="noopener noreferrer"
>
<div className={s.authorLinkText}>
<span title={user.name}>{user.name}</span>
</div>
<VerifiedBadge user={user} className={s.authorVerified} />
</a>
<div className={s.authorMeta}>
<a
href={tweet.url}
className={s.username}
target="_blank"
rel="noopener noreferrer"
>
<span title={`@${user.screen_name}`}>@{user.screen_name}</span>
</a>
<div className={s.authorFollow}>
<span className={s.separator}>·</span>
<a
href={user.follow_url}
className={s.follow}
target="_blank"
rel="noopener noreferrer"
>
Follow
</a>
</div>
</div>
</div>
</div>
);
};
export const MyTweet = ({ tweet: t, components }: Props) => {
if ("error" in t) {
return <div>{t.error}</div>;
}
const tweet = enrichTweet(t);
return (
<TweetContainer className="bg-transparent !m-0 !p-0 !z-0">
<TweetHeader tweet={tweet} components={components} />
{tweet.in_reply_to_status_id_str && <TweetInReplyTo tweet={tweet} />}
<TweetBody tweet={tweet} />
{tweet.mediaDetails?.length ? (
<TweetMedia tweet={tweet} components={components} />
) : null}
{tweet.quoted_tweet && <QuotedTweet tweet={tweet.quoted_tweet} />}
<TweetInfo tweet={tweet} />
</TweetContainer>
);
};
|