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