a demonstration replicated social networking web app built with anproto
wiredove.net/
social
ed25519
protocols
1import {h} from 'h'
2import {apds} from 'apds'
3
4const nameDiv = async () => {
5 const name = await apds.get('name')
6
7 const namer = h('input', {
8 placeholder: name || 'Name yourself'
9 })
10
11 const namerDiv = h('span', [
12 namer,
13 h('button', {onclick: async () => {
14 if (namer.value) {
15 namer.placeholder = namer.value
16 await apds.put('name', namer.value)
17 namer.value = ''
18 namerDiv.replaceWith(await genDiv())
19 }
20 }}, ['Save'])
21 ])
22
23 return namerDiv
24}
25
26const saveButton = async (keypair) => {
27 const button = h('button', {
28 id: 'saveButton',
29 onclick: async () => {
30 await apds.put('keypair', keypair)
31 document.location.reload()
32 }
33 }, ['Save'])
34
35 return button
36}
37
38export const genDiv = async () => {
39 const initial = await apds.generate()
40 const name = await apds.get('name')
41 const pubkey = h('span', {classList: 'pubkey'})
42 const button = h('button', {
43 onclick: async () => {
44 if (name.length > 1) {
45 const alreadyButton = document.getElementById('saveButton')
46 if (alreadyButton) { alreadyButton.remove() }
47 let done = true
48 const genInterval = setInterval(async _ => {
49 const keypair = await apds.generate()
50 pubkey.textContent = keypair.substring(0, 10)
51 if (keypair.substring(0, 2).toUpperCase() === name.substring(0, 2).toUpperCase()) {
52 clearInterval(genInterval)
53 pubkey.after(await saveButton(keypair))
54 }
55 }, .000001)
56 } else {
57 await apds.put('keypair', initial)
58 document.location.reload()
59 }
60 }
61 }, ['Generate'])
62 button.click()
63 const div = h('span', [
64 h('span', [name]),
65 button,
66 ' ',
67 pubkey,
68 ' ',
69 ])
70 return div
71}
72
73export const identify = async () => {
74 const span = h('span')
75
76 const start = h('button', {
77 id: 'generate-keypair-button',
78 onclick: async () => {
79 const div2 = h('span', [
80 await nameDiv()
81 ])
82
83 div1.replaceWith(div2)
84 }
85 }, ['Generate Keypair'])
86
87 const div1 = h('span', [start])
88
89
90 if (!await apds.pubkey()) {
91 span.appendChild(div1)
92 }
93 return span
94}
95
96export const promptKeypair = (message = 'Generate a keypair to post or reply.') => {
97 const button = document.getElementById('generate-keypair-button')
98 if (button) {
99 button.classList.add('keypair-highlight')
100 button.focus?.()
101 setTimeout(() => {
102 button.classList.remove('keypair-highlight')
103 }, 1800)
104 }
105
106 const existing = document.getElementById('keypair-notice')
107 const notice = existing || h('div', {id: 'keypair-notice', classList: 'keypair-notice'}, [''])
108 notice.textContent = message
109 notice.classList.add('show')
110
111 if (!existing) {
112 const navbar = document.getElementById('navbar')
113 if (navbar && navbar.parentNode) {
114 navbar.parentNode.insertBefore(notice, navbar.nextSibling)
115 } else {
116 document.body.appendChild(notice)
117 }
118 }
119
120 setTimeout(() => {
121 notice.classList.remove('show')
122 }, 3000)
123}