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 myStatus?: Status
41}
42
43export function home(props: Props) {
44 return shell({
45 title: 'Home',
46 content: content(props),
47 })
48}
49
50function content({ statuses, didHandleMap, profile, myStatus }: Props) {
51 return html`<div id="root">
52 <div class="error"></div>
53 <div id="header">
54 <h1>Statusphere</h1>
55 <p>Set your status on the Atmosphere.</p>
56 </div>
57 <div class="container">
58 <div class="card">
59 ${profile
60 ? html`<form action="/logout" method="post" class="session-form">
61 <div>
62 Hi, <strong>${profile.displayName || profile.handle}</strong>.
63 what's your status today?
64 </div>
65 <div>
66 <button type="submit">Log out</button>
67 </div>
68 </form>`
69 : html`<div class="session-form">
70 <div><a href="/login">Log in</a> to set your status!</div>
71 <div>
72 <a href="/login" class="button">Log in</a>
73 </div>
74 </div>`}
75 </div>
76 <div class="status-options">
77 ${STATUS_OPTIONS.map(
78 (status) =>
79 html`<div
80 class=${myStatus?.status === status
81 ? 'status-option selected'
82 : 'status-option'}
83 data-value="${status}"
84 data-authed=${profile ? '1' : '0'}
85 >
86 ${status}
87 </div>`
88 )}
89 </div>
90 ${statuses.map((status, i) => {
91 const handle = didHandleMap[status.authorDid] || status.authorDid
92 return html`
93 <div class=${i === 0 ? 'status-line no-line' : 'status-line'}>
94 <div>
95 <div class="status">${status.status}</div>
96 </div>
97 <div class="desc">
98 <a class="author" href=${toBskyLink(handle)}>@${handle}</a>
99 is feeling ${status.status} on ${ts(status)}
100 </div>
101 </div>
102 `
103 })}
104 </div>
105 <script src="/public/home.js"></script>
106 </div>`
107}
108
109function toBskyLink(did: string) {
110 return `https://bsky.app/profile/${did}`
111}
112
113function ts(status: Status) {
114 const indexedAt = new Date(status.indexedAt)
115 const updatedAt = new Date(status.updatedAt)
116 if (updatedAt > indexedAt) return updatedAt.toDateString()
117 return indexedAt.toDateString()
118}