search and/or read your saved and liked bluesky posts
wails
go
svelte
sqlite
desktop
bluesky
1<script lang="ts">
2 import { parseFacets, renderFacets, truncateRenderedFacets } from "../facets";
3
4 type Props = { text: string; facetsJson?: string; maxLength?: number; class?: string };
5
6 let { text, facetsJson = "", maxLength = 0, class: className = "" }: Props = $props();
7
8 let renderedFacets = $derived.by(() => {
9 const facets = parseFacets(facetsJson);
10 const rendered = renderFacets(text, facets);
11
12 if (maxLength > 0 && maxLength < text.length) {
13 const { facets: truncated } = truncateRenderedFacets(rendered, maxLength);
14 return truncated;
15 }
16
17 return rendered;
18 });
19</script>
20
21<span class={className}>
22 {#each renderedFacets as facet}
23 {#if facet.type === "link"}
24 <a
25 href={facet.href}
26 target="_blank"
27 rel="noopener noreferrer"
28 class="text-primary hover:text-primary-bright hover:underline"
29 onclick={(e) => e.stopPropagation()}>
30 {facet.text}
31 </a>
32 {:else if facet.type === "mention"}
33 <a
34 href={facet.href}
35 target="_blank"
36 rel="noopener noreferrer"
37 class="text-primary hover:text-primary-bright hover:underline"
38 onclick={(e) => e.stopPropagation()}>
39 {facet.text}
40 </a>
41 {:else if facet.type === "tag"}
42 <a
43 href={facet.href}
44 target="_blank"
45 rel="noopener noreferrer"
46 class="text-secondary hover:text-secondary-bright hover:underline"
47 onclick={(e) => e.stopPropagation()}>
48 {facet.text}
49 </a>
50 {:else}
51 <span class="font-sans">{facet.text}</span>
52 {/if}
53 {/each}
54</span>