Fork of atp.tools as a universal profile for people on the ATmosphere
1import { segmentize } from "@atcute/bluesky-richtext-segmenter";
2import { AppBskyRichtextFacet } from "@atcute/client/lexicons";
3import { Link } from "@tanstack/react-router";
4import React from "preact/compat";
5
6interface SegmentedInput {
7 text: string;
8 facets: AppBskyRichtextFacet.Main[];
9}
10
11export function SplitText({ text }: { text: string }) {
12 console.log(text);
13 return (
14 <>
15 {text.split("\n").map((line, i) => (
16 <React.Fragment key={i}>
17 {line}
18 {i !== text.split("\n").length - 1 && <br />}
19 </React.Fragment>
20 ))}
21 </>
22 );
23}
24
25export function SegmentedText({ text, facets }: SegmentedInput) {
26 const segments = segmentize(text, facets);
27 return (
28 <span>
29 {segments.map((segment, index) => {
30 if (!segment.features || segment.features.length === 0) {
31 return (
32 <span key={index}>
33 <SplitText text={segment.text} />
34 </span>
35 );
36 }
37 switch (segment.features[0].$type) {
38 case "app.bsky.richtext.facet#link": {
39 return (
40 <a
41 key={index}
42 href={segment.features[0].uri}
43 target="_blank"
44 rel="noreferrer"
45 className="text-blue-500 font-bold inline"
46 >
47 <SplitText text={segment.text} />
48 </a>
49 );
50 }
51 case "app.bsky.richtext.facet#mention": {
52 return (
53 <Link
54 to={`/at:/$handle`}
55 params={{ handle: segment.features[0].did }}
56 key={index}
57 className="text-blue-500 font-bold"
58 >
59 <SplitText text={segment.text} />
60 </Link>
61 );
62 }
63 case "app.bsky.richtext.facet#tag": {
64 return (
65 <a
66 href={`https://bsky.app/hashtag/${segment.features[0].tag}`}
67 key={index}
68 className="text-blue-500 font-bold"
69 >
70 <SplitText text={segment.text} />
71 </a>
72 );
73 }
74 default: {
75 return (
76 <span key={index}>
77 <SplitText text={segment.text} />
78 </span>
79 );
80 }
81 }
82 })}
83 </span>
84 );
85}