Scratch space for learning atproto app development
1import { AtUri } from '@atproto/syntax' 2import type { Status } from '#/db/schema' 3import { html } from '../view' 4import { shell } from './shell' 5 6const STATUS_OPTIONS = [ 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 36type Props = { 37 statuses: Status[] 38 didHandleMap: Record<string, string> 39 profile?: { displayName?: string; handle: string } 40} 41 42export function home(props: Props) { 43 return shell({ 44 title: 'Home', 45 content: content(props), 46 }) 47} 48 49function content({ statuses, didHandleMap, profile }: Props) { 50 return html`<div id="root"> 51 <div class="error"></div> 52 <div id="header"> 53 <h1>Statusphere</h1> 54 <p>Set your status on the Atmosphere.</p> 55 </div> 56 <div class="container"> 57 <div class="card"> 58 ${profile 59 ? html`<form action="/logout" method="post" class="session-form"> 60 <div> 61 Hi, <strong>${profile.displayName || profile.handle}</strong>. 62 what's your status today? 63 </div> 64 <div> 65 <button type="submit">Log out</button> 66 </div> 67 </form>` 68 : html`<p><a href="/login">Log in</a> to set your status!</p>`} 69 </div> 70 <div class=""> 71 <div class="status-options"> 72 ${STATUS_OPTIONS.map( 73 (status) => 74 html`<div class="status-option" data-value="${status}"> 75 ${status} 76 </div>` 77 )} 78 </div> 79 </div> 80 <div class="status-line no-line"> 81 <div class="status">👍</div> 82 <div class="desc"> 83 <a class="author" href="/">@pfrazee.com</a> 84 is feeling 👍 on Aug 12, 2024 85 </div> 86 </div> 87 <div class="status-line"> 88 <div class="status">👍</div> 89 <div class="desc"> 90 <a class="author" href="/">@pfrazee.com</a> 91 is feeling 👍 on Aug 12, 2024 92 </div> 93 </div> 94 <div class="status-line"> 95 <div class="status">👍</div> 96 <div class="desc"> 97 <a class="author" href="/">@pfrazee.com</a> 98 is feeling 👍 on Aug 12, 2024 99 </div> 100 </div> 101 <div class="status-line"> 102 <div class="status">👍</div> 103 <div class="desc"> 104 <a class="author" href="/">@pfrazee.com</a> 105 is feeling 👍 on Aug 12, 2024 106 </div> 107 </div> 108 <div class="status-line"> 109 <div class="status">👍</div> 110 <div class="desc"> 111 <a class="author" href="/">@pfrazee.com</a> 112 is feeling 👍 on Aug 12, 2024 113 </div> 114 </div> 115 <div class="status-line"> 116 <div class="status">👍</div> 117 <div class="desc"> 118 <a class="author" href="/">@pfrazee.com</a> 119 is feeling 👍 on Aug 12, 2024 120 </div> 121 </div> 122 ${statuses.map((status, i) => { 123 const handle = didHandleMap[status.authorDid] || status.authorDid 124 return html` 125 <div class=${i === 0 ? 'status-line no-line' : 'status-line'}> 126 <div> 127 <div class="status">${status.status}</div> 128 </div> 129 <div class="desc"> 130 <a class="author" href=${toBskyLink(handle)}>@${handle}</a> 131 is feeling ${status.status} on ${ts(status)} 132 </div> 133 </div> 134 ` 135 })} 136 </div> 137 <script src="/public/home.js"></script> 138 </div>` 139} 140 141function toBskyLink(did: string) { 142 return `https://bsky.app/profile/${did}` 143} 144 145function ts(status: Status) { 146 const indexedAt = new Date(status.indexedAt) 147 const updatedAt = new Date(status.updatedAt) 148 if (updatedAt > indexedAt) return updatedAt.toDateString() 149 return indexedAt.toDateString() 150}