git ssb

16+

Dominic / patchbay



Tree: ed0d0518717fe16a686399588766fb35b3e6e37a

Files: ed0d0518717fe16a686399588766fb35b3e6e37a / app / page / network / invite-peer.js

5408 bytesRaw
1const { h, Value, resolve, onceTrue, when, computed } = require('mutant')
2// const { isInvite } = require('ssb-ref')
3
4function isInvite (code) {
5 return typeof code === 'string' &&
6 code.length > 32 &&
7 code.startsWith('inv:') &&
8 code.endsWith('=')
9 // TODO find actual peer-invite validator!
10}
11
12module.exports = function InvitePeer ({ connection }) {
13 const state = {
14 use: {
15 invite: Value(),
16 opening: Value(false),
17 message: Value(null),
18 accepting: Value(false),
19 result: Value(null)
20 },
21 create: {
22 input: {
23 private: Value(),
24 reveal: Value()
25 },
26 processing: Value(false),
27 time: Value(),
28 result: Value()
29 }
30 }
31
32 const body = h('InvitePeer', [
33 h('p', [
34 h('i.fa.fa-warning'),
35 ' BETA - peer invites are still being rolled out to pubs and tested.'
36 ]),
37 h('div.use', [
38 h('textarea', {
39 'placeholder': 'peer invite code',
40 'ev-input': handleInput
41 }),
42 // MIX : I hate this, it's a mess. There's a state machine emerging, but I don't have time to build it right now
43 computed(
44 [state.use.invite, state.use.opening, state.use.message, state.use.accepting],
45 (invite, opening, message, accepting) => {
46 if (opening || accepting) {
47 return [
48 h('button', { disabled: 'disabled' }, [
49 h('i.fa.fa-spinner.fa-pulse')
50 ])
51 ]
52 }
53
54 return [
55 message && message.private ? h('div.private', message.private) : '',
56 message && message.reveal ? h('div.private', message.reveal) : '',
57 message
58 ? h('button -primary', { 'ev-click': acceptInvite }, 'accept invitation')
59 : invite
60 ? h('button -primary', { 'ev-click': openInvite }, 'use invite')
61 : h('button', { disabled: 'disabled', title: 'not a valid invite code' }, 'use invite')
62 ]
63 }
64 ),
65 computed(state.use.result, result => {
66 if (result === null) return
67
68 return result
69 ? h('i.fa.fa-check')
70 : h('i.fa.fa-times')
71 })
72 ]),
73 h('div.create', [
74 h('p', 'make a new peer invite code:'),
75 h('div.form', [
76 h('div.inputs', [
77 h('textarea.private', {
78 placeholder: 'private message your friend will see when they open this invite',
79 'ev-input': (ev) => state.create.input.private.set(ev.target.value)
80 }),
81 h('textarea.reveal', {
82 placeholder: 'an introduction message which the community will be able to read when this invite is accepted',
83 'ev-input': (ev) => state.create.input.reveal.set(ev.target.value)
84 })
85 ]),
86 h('button', {
87 'ev-click': createInvite,
88 disabled: state.create.processing
89 }, 'create peer-invite')
90 ]),
91 h('div.result', [
92 when(state.create.processing, [
93 'creating an peer invite takes some time.',
94 h('br'),
95 'time so far: ',
96 state.create.time
97 ]),
98 when(state.create.result, h('div.code', [
99 h('code', state.create.result)
100 ]))
101 ])
102 ])
103 ])
104
105 function createInvite () {
106 state.create.processing.set(true)
107 var start = Date.now()
108 var SECOND = 1e3
109 var MINUTE = 60 * SECOND
110
111 onceTrue(connection, sbot => {
112 var interval = setInterval(
113 () => {
114 const dt = Date.now() - start
115 const mins = Math.floor(dt / MINUTE)
116 const secs = Math.floor((dt - mins * MINUTE) / SECOND)
117 state.create.time.set(`${mins} mins, ${secs} seconds`)
118 },
119 SECOND
120 )
121
122 const opts = {
123 private: resolve(state.create.input.private),
124 reveal: resolve(state.create.input.reveal)
125 }
126
127 sbot.peerInvites.create(opts, (err, invite) => {
128 if (err) return console.error(err)
129
130 clearInterval(interval)
131 state.create.result.set(invite)
132 state.create.processing.set(false)
133 })
134 })
135 }
136
137 function handleInput (ev) {
138 state.use.result.set(null)
139 const invite = ev.target.value.replace(/^\s*"?/, '').replace(/"?\s*$/, '')
140
141 if (!isInvite(invite)) return
142
143 ev.target.value = invite
144 state.use.invite.set(invite)
145 }
146
147 function openInvite () {
148 state.use.opening.set(true)
149
150 onceTrue(connection, server => {
151 server.peerInvites.openInvite(resolve(state.use.invite), (err, data) => {
152 state.use.opening.set(false)
153 if (err) {
154 state.use.result.set(false)
155 console.error(err)
156 return
157 }
158
159 console.log(err, data) // NOTE no opened arriving ...
160 // HACK
161 const m = data.opened || {
162 private: 'kiaora gorgeous, welcome'
163 }
164 state.use.message.set(m)
165 })
166 })
167 }
168
169 function acceptInvite () {
170 state.use.accepting.set(true)
171
172 onceTrue(connection, server => {
173 server.peerInvites.acceptInvite(resolve(state.use.invite), (err, confirm) => {
174 state.use.accepting.set(false)
175 if (err) {
176 state.use.result.set(false)
177 console.error(err)
178 return
179 }
180
181 console.log('peerInvites.acceptInvite worked:', confirm)
182 state.use.result.set(true)
183 })
184 })
185 }
186
187 return {
188 title: 'peer invites',
189 body
190 }
191}
192

Built with git-ssb-web