diff options
| author | Dhravya <[email protected]> | 2024-07-01 20:12:56 -0500 |
|---|---|---|
| committer | Dhravya <[email protected]> | 2024-07-01 20:12:56 -0500 |
| commit | 2c6a96e96f49439853f68ff18d1502cac04d618c (patch) | |
| tree | c4b541c4ba21bf1b404722d714d5ab32a2644d90 /apps/web/components | |
| parent | fix link (diff) | |
| download | supermemory-2c6a96e96f49439853f68ff18d1502cac04d618c.tar.xz supermemory-2c6a96e96f49439853f68ff18d1502cac04d618c.zip | |
spaces function
Diffstat (limited to 'apps/web/components')
| -rw-r--r-- | apps/web/components/twitter/icons/icons.module.css | 9 | ||||
| -rw-r--r-- | apps/web/components/twitter/icons/index.ts | 3 | ||||
| -rw-r--r-- | apps/web/components/twitter/icons/verified-business.tsx | 53 | ||||
| -rw-r--r-- | apps/web/components/twitter/icons/verified-government.tsx | 18 | ||||
| -rw-r--r-- | apps/web/components/twitter/icons/verified.tsx | 14 | ||||
| -rw-r--r-- | apps/web/components/twitter/render-tweet.tsx | 117 | ||||
| -rw-r--r-- | apps/web/components/twitter/tweet-header.module.css | 96 | ||||
| -rw-r--r-- | apps/web/components/twitter/verified-badge.module.css | 10 | ||||
| -rw-r--r-- | apps/web/components/twitter/verified-badge.tsx | 34 |
9 files changed, 354 insertions, 0 deletions
diff --git a/apps/web/components/twitter/icons/icons.module.css b/apps/web/components/twitter/icons/icons.module.css new file mode 100644 index 00000000..aca493e6 --- /dev/null +++ b/apps/web/components/twitter/icons/icons.module.css @@ -0,0 +1,9 @@ +.verified { + margin-left: 0.125rem; + max-width: 20px; + max-height: 20px; + height: 1.25em; + fill: currentColor; + user-select: none; + vertical-align: text-bottom; +} diff --git a/apps/web/components/twitter/icons/index.ts b/apps/web/components/twitter/icons/index.ts new file mode 100644 index 00000000..f90ec616 --- /dev/null +++ b/apps/web/components/twitter/icons/index.ts @@ -0,0 +1,3 @@ +export * from "./verified"; +export * from "./verified-business"; +export * from "./verified-government"; diff --git a/apps/web/components/twitter/icons/verified-business.tsx b/apps/web/components/twitter/icons/verified-business.tsx new file mode 100644 index 00000000..06d574bd --- /dev/null +++ b/apps/web/components/twitter/icons/verified-business.tsx @@ -0,0 +1,53 @@ +import s from "./icons.module.css"; + +export const VerifiedBusiness = () => ( + <svg + viewBox="0 0 22 22" + aria-label="Verified account" + role="img" + className={s.verified} + > + <g> + <linearGradient + gradientUnits="userSpaceOnUse" + id="0-a" + x1="4.411" + x2="18.083" + y1="2.495" + y2="21.508" + > + <stop offset="0" stopColor="#f4e72a"></stop> + <stop offset=".539" stopColor="#cd8105"></stop> + <stop offset=".68" stopColor="#cb7b00"></stop> + <stop offset="1" stopColor="#f4ec26"></stop> + <stop offset="1" stopColor="#f4e72a"></stop> + </linearGradient> + <linearGradient + gradientUnits="userSpaceOnUse" + id="0-b" + x1="5.355" + x2="16.361" + y1="3.395" + y2="19.133" + > + <stop offset="0" stopColor="#f9e87f"></stop> + <stop offset=".406" stopColor="#e2b719"></stop> + <stop offset=".989" stopColor="#e2b719"></stop> + </linearGradient> + <g clipRule="evenodd" fillRule="evenodd"> + <path + d="M13.324 3.848L11 1.6 8.676 3.848l-3.201-.453-.559 3.184L2.06 8.095 3.48 11l-1.42 2.904 2.856 1.516.559 3.184 3.201-.452L11 20.4l2.324-2.248 3.201.452.559-3.184 2.856-1.516L18.52 11l1.42-2.905-2.856-1.516-.559-3.184zm-7.09 7.575l3.428 3.428 5.683-6.206-1.347-1.247-4.4 4.795-2.072-2.072z" + fill="url(#0-a)" + ></path> + <path + d="M13.101 4.533L11 2.5 8.899 4.533l-2.895-.41-.505 2.88-2.583 1.37L4.2 11l-1.284 2.627 2.583 1.37.505 2.88 2.895-.41L11 19.5l2.101-2.033 2.895.41.505-2.88 2.583-1.37L17.8 11l1.284-2.627-2.583-1.37-.505-2.88zm-6.868 6.89l3.429 3.428 5.683-6.206-1.347-1.247-4.4 4.795-2.072-2.072z" + fill="url(#0-b)" + ></path> + <path + d="M6.233 11.423l3.429 3.428 5.65-6.17.038-.033-.005 1.398-5.683 6.206-3.429-3.429-.003-1.405.005.003z" + fill="#d18800" + ></path> + </g> + </g> + </svg> +); diff --git a/apps/web/components/twitter/icons/verified-government.tsx b/apps/web/components/twitter/icons/verified-government.tsx new file mode 100644 index 00000000..601a6910 --- /dev/null +++ b/apps/web/components/twitter/icons/verified-government.tsx @@ -0,0 +1,18 @@ +import s from "./icons.module.css"; + +export const VerifiedGovernment = () => ( + <svg + viewBox="0 0 22 22" + aria-label="Verified account" + role="img" + className={s.verified} + > + <g> + <path + clipRule="evenodd" + d="M12.05 2.056c-.568-.608-1.532-.608-2.1 0l-1.393 1.49c-.284.303-.685.47-1.1.455L5.42 3.932c-.832-.028-1.514.654-1.486 1.486l.069 2.039c.014.415-.152.816-.456 1.1l-1.49 1.392c-.608.568-.608 1.533 0 2.101l1.49 1.393c.304.284.47.684.456 1.1l-.07 2.038c-.027.832.655 1.514 1.487 1.486l2.038-.069c.415-.014.816.152 1.1.455l1.392 1.49c.569.609 1.533.609 2.102 0l1.393-1.49c.283-.303.684-.47 1.099-.455l2.038.069c.832.028 1.515-.654 1.486-1.486L18 14.542c-.015-.415.152-.815.455-1.099l1.49-1.393c.608-.568.608-1.533 0-2.101l-1.49-1.393c-.303-.283-.47-.684-.455-1.1l.068-2.038c.029-.832-.654-1.514-1.486-1.486l-2.038.07c-.415.013-.816-.153-1.1-.456zm-5.817 9.367l3.429 3.428 5.683-6.206-1.347-1.247-4.4 4.795-2.072-2.072z" + fillRule="evenodd" + ></path> + </g> + </svg> +); diff --git a/apps/web/components/twitter/icons/verified.tsx b/apps/web/components/twitter/icons/verified.tsx new file mode 100644 index 00000000..81c9fc25 --- /dev/null +++ b/apps/web/components/twitter/icons/verified.tsx @@ -0,0 +1,14 @@ +import s from "./icons.module.css"; + +export const Verified = () => ( + <svg + viewBox="0 0 24 24" + aria-label="Verified account" + role="img" + className={s.verified} + > + <g> + <path d="M22.25 12c0-1.43-.88-2.67-2.19-3.34.46-1.39.2-2.9-.81-3.91s-2.52-1.27-3.91-.81c-.66-1.31-1.91-2.19-3.34-2.19s-2.67.88-3.33 2.19c-1.4-.46-2.91-.2-3.92.81s-1.26 2.52-.8 3.91c-1.31.67-2.2 1.91-2.2 3.34s.89 2.67 2.2 3.34c-.46 1.39-.21 2.9.8 3.91s2.52 1.26 3.91.81c.67 1.31 1.91 2.19 3.34 2.19s2.68-.88 3.34-2.19c1.39.45 2.9.2 3.91-.81s1.27-2.52.81-3.91c1.31-.67 2.19-1.91 2.19-3.34zm-11.71 4.2L6.8 12.46l1.41-1.42 2.26 2.26 4.8-5.23 1.47 1.36-6.2 6.77z"></path> + </g> + </svg> +); diff --git a/apps/web/components/twitter/render-tweet.tsx b/apps/web/components/twitter/render-tweet.tsx new file mode 100644 index 00000000..9d6d1a8a --- /dev/null +++ b/apps/web/components/twitter/render-tweet.tsx @@ -0,0 +1,117 @@ +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; + 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) => { + 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> + ); +}; diff --git a/apps/web/components/twitter/tweet-header.module.css b/apps/web/components/twitter/tweet-header.module.css new file mode 100644 index 00000000..2ce994e2 --- /dev/null +++ b/apps/web/components/twitter/tweet-header.module.css @@ -0,0 +1,96 @@ +.header { + display: flex; + padding-bottom: 0.75rem; + line-height: var(--tweet-header-line-height); + font-size: var(--tweet-header-font-size); + white-space: nowrap; + overflow-wrap: break-word; + overflow: hidden; +} + +.avatar { + position: relative; + height: 48px; + width: 48px; +} +.avatarOverflow { + height: 100%; + width: 100%; + position: absolute; + overflow: hidden; + border-radius: 9999px; +} +.avatarSquare { + border-radius: 4px; +} +.avatarShadow { + height: 100%; + width: 100%; + transition-property: background-color; + transition-duration: 0.2s; + box-shadow: rgb(0 0 0 / 3%) 0px 0px 2px inset; +} +.avatarShadow:hover { + background-color: rgba(26, 26, 26, 0.15); +} + +.author { + max-width: calc(100% - 84px); + display: flex; + flex-direction: column; + justify-content: center; + margin: 0 0.5rem; +} +.authorLink { + text-decoration: none; + color: inherit; + display: flex; + align-items: center; +} +.authorLink:hover { + text-decoration-line: underline; +} +.authorVerified { + display: inline-flex; +} +.authorLinkText { + font-weight: 700; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; +} + +.authorMeta { + display: flex; +} +.authorFollow { + display: flex; +} +.username { + color: var(--tweet-font-color-secondary); + text-decoration: none; + text-overflow: ellipsis; +} +.follow { + color: var(--tweet-color-blue-secondary); + text-decoration: none; + font-weight: 700; +} +.follow:hover { + text-decoration-line: underline; +} +.separator { + padding: 0 0.25rem; +} + +.brand { + margin-inline-start: auto; +} + +.twitterIcon { + width: 23.75px; + height: 23.75px; + color: var(--tweet-twitter-icon-color); + fill: currentColor; + user-select: none; +} diff --git a/apps/web/components/twitter/verified-badge.module.css b/apps/web/components/twitter/verified-badge.module.css new file mode 100644 index 00000000..c16e77ec --- /dev/null +++ b/apps/web/components/twitter/verified-badge.module.css @@ -0,0 +1,10 @@ +.verifiedOld { + color: var(--tweet-verified-old-color); +} +.verifiedBlue { + color: var(--tweet-verified-blue-color); +} +.verifiedGovernment { + /* color: var(--tweet-verified-government-color); */ + color: rgb(130, 154, 171); +} diff --git a/apps/web/components/twitter/verified-badge.tsx b/apps/web/components/twitter/verified-badge.tsx new file mode 100644 index 00000000..daa11852 --- /dev/null +++ b/apps/web/components/twitter/verified-badge.tsx @@ -0,0 +1,34 @@ +import clsx from "clsx"; +import { Verified, VerifiedBusiness, VerifiedGovernment } from "./icons/index"; +import s from "./verified-badge.module.css"; + +type Props = { + user: any; + className?: string; +}; + +export const VerifiedBadge = ({ user, className }: Props) => { + const verified = user.verified || user.is_blue_verified || user.verified_type; + let icon = <Verified />; + let iconClassName: string | null = s.verifiedBlue ?? null; + + if (verified) { + if (!user.is_blue_verified) { + iconClassName = s.verifiedOld!; + } + switch (user.verified_type) { + case "Government": + icon = <VerifiedGovernment />; + iconClassName = s.verifiedGovernment!; + break; + case "Business": + icon = <VerifiedBusiness />; + iconClassName = null; + break; + } + } + + return verified ? ( + <div className={clsx(className, iconClassName)}>{icon}</div> + ) : null; +}; |