search and/or read your saved and liked bluesky posts
wails go svelte sqlite desktop bluesky
at main 98 lines 3.9 kB view raw
1<script lang="ts"> 2 import { BrowserOpenURL } from "../../../wailsjs/runtime/runtime"; 3 import type { main } from "../../../wailsjs/go/models"; 4 import PostText from "./PostText.svelte"; 5 import { formatLongDateTime } from "../date"; 6 7 interface Props { 8 post: main.SearchResult; 9 onClose: () => void; 10 } 11 12 let { post, onClose }: Props = $props(); 13 14 function buildPostURL(uri: string): string { 15 const match = uri.match(/at:\/\/([^/]+)\/app\.bsky\.feed\.post\/(.+)/); 16 if (match) { 17 return `https://bsky.app/profile/${match[1]}/post/${match[2]}`; 18 } 19 return uri; 20 } 21 22 function openInBrowser() { 23 BrowserOpenURL(buildPostURL(post.uri)); 24 } 25</script> 26 27<aside 28 class="border-outline bg-surface/95 flex h-full min-h-0 w-full flex-col overflow-hidden rounded-[1.25rem] border shadow-[0_24px_80px_rgba(0,0,0,0.45)] backdrop-blur xl:w-100 xl:min-w-100"> 29 <header class="border-outline border-b bg-black/80 px-5 py-4"> 30 <div class="flex items-start justify-between gap-4"> 31 <div class="min-w-0"> 32 <p class="text-muted font-mono text-[11px] tracking-[0.3em] uppercase">Reading Pane</p> 33 <h2 class="text-bright mt-2 truncate font-serif text-2xl">@{post.author_handle}</h2> 34 <p class="text-muted mt-1 font-mono text-xs">{formatLongDateTime(post.created_at)}</p> 35 </div> 36 37 <button 38 type="button" 39 onclick={onClose} 40 class="border-outline bg-surface text-muted hover:text-bright rounded-full border px-3 py-1.5 font-mono text-xs transition-colors"> 41 Close 42 </button> 43 </div> 44 </header> 45 46 <div class="flex-1 overflow-y-auto px-5 py-5"> 47 <div class="border-outline rounded-2xl border bg-black/60 p-5"> 48 <div class="mb-5 flex flex-wrap gap-2"> 49 <span 50 class="bg-primary/15 text-primary rounded-full px-3 py-1 font-mono text-[11px] tracking-[0.18em] uppercase"> 51 {post.source} 52 </span> 53 <span 54 class="border-outline text-muted flex items-center gap-1 rounded-full border px-3 py-1 font-mono text-[11px]"> 55 <i class="i-ri-heart-line"></i> 56 <span>{post.like_count || 0}</span> 57 </span> 58 <span class="border-outline text-muted flex items-center rounded-full border px-3 py-1 font-mono text-[11px]"> 59 <i class="i-ri-repeat-line"></i> 60 <span>{post.repost_count || 0}</span> 61 </span> 62 <span class="border-outline text-muted flex items-center rounded-full border px-3 py-1 font-mono text-[11px]"> 63 <i class="i-ri-message-2-line"></i> 64 <span>{post.reply_count || 0}</span> 65 </span> 66 </div> 67 68 <div class="space-y-4"> 69 <p class="text-muted font-mono text-xs tracking-[0.22em] uppercase">Post</p> 70 <div class="text-bright font-mono text-sm leading-7 text-pretty"> 71 <PostText text={post.text} facetsJson={post.facets} /> 72 </div> 73 </div> 74 </div> 75 76 <dl class="border-outline bg-surface/80 mt-5 grid gap-4 rounded-2xl border p-4"> 77 <div> 78 <dt class="text-muted font-mono text-[11px] tracking-[0.2em] uppercase">Post URI</dt> 79 <dd class="text-bright mt-1 font-mono text-xs break-all">{post.uri}</dd> 80 </div> 81 <div> 82 <dt class="text-muted font-mono text-[11px] tracking-[0.2em] uppercase">Indexed</dt> 83 <dd class="text-bright mt-1 font-mono text-xs">{formatLongDateTime(post.indexed_at)}</dd> 84 </div> 85 </dl> 86 </div> 87 88 <footer class="border-outline border-t bg-black/75 px-5 py-4"> 89 <button 90 type="button" 91 onclick={openInBrowser} 92 class="border-outline bg-surface text-bright hover:bg-outline flex w-full items-center rounded-xl border px-4 py-3 font-sans text-sm transition-colors"> 93 <span>Open on BlueSky</span> 94 <i class="i-ri-blue-sky-fill m-2"></i> 95 <i class="i-ri-external-link-line"></i> 96 </button> 97 </footer> 98</aside>