eleven / ocho Public

Clone
git clone https://amadan.net/eleven/ocho

Plain git — no account needed to clone.

Download

Download this file

1{
2 "schema": 1,
3 "flow": "welcome",
4 "entry": "hello",
5 "resumedIf": {
6 "any": [
7 "done.access",
8 "done.name",
9 "bridge.myName"
10 ]
11 },
12 "resumeUnless": {
13 "all": [
14 "bridge.enrolled",
15 "!done.access"
16 ]
17 },
18 "resumeSay": "Welcome back β€” let's pick up where we left off.",
19 "steps": [
20 {
21 "id": "hello",
22 "skipIf": [
23 "resumed"
24 ],
25 "bubbles": [
26 {
27 "text": [
28 "Welcome! πŸ‘‹ I'm Eleven, your guide here.\n\n",
29 {
30 "if": "inviterName",
31 "text": "{inviterName} invited you to {space.name|this space}"
32 },
33 {
34 "if": "!inviterName",
35 "text": "You've been invited to {space.name|this space}"
36 },
37 " β€” a private, invite-only chat space. It isn't a big platform with accounts and feeds: it's a small server ",
38 {
39 "if": "adminName",
40 "text": "run by {adminName}"
41 },
42 {
43 "if": "!adminName",
44 "text": "run by one of its members"
45 },
46 ", just for the people in it.\n\n",
47 "Everything here β€” messages, photos, even names β€” is locked with keys only members hold, so nobody outside a chat can ever read it. Not the server, and not whoever runs it."
48 ]
49 }
50 ],
51 "auto": "access"
52 },
53 {
54 "id": "access",
55 "entries": [
56 {
57 "if": {
58 "all": [
59 "native",
60 "bridge.homeSignedIn"
61 ]
62 },
63 "recordIfNew": {
64 "label": "Your access is already secured by your Eleven sign-in",
65 "value": "native"
66 },
67 "goto": "name"
68 },
69 {
70 "if": {
71 "any": [
72 "bridge.enrolled",
73 "done"
74 ]
75 },
76 "recordIfNew": {
77 "label": "Signed in β€” your access is safe",
78 "value": "passkey"
79 },
80 "sayIfNew": "Great β€” you're signed in, so your access is safe. πŸ”’ Let's continue.",
81 "goto": "name"
82 },
83 {
84 "if": "!bridge.canEnrol",
85 "recordIfNew": {
86 "label": {
87 "if": "native",
88 "then": "Your access lives on this device",
89 "else": "Your access lives in this browser"
90 },
91 "value": "local"
92 },
93 "goto": "name"
94 }
95 ],
96 "settle": {
97 "when": {
98 "any": [
99 "bridge.enrolled",
100 "bridge.homeSignedIn"
101 ]
102 }
103 },
104 "bubbles": [
105 {
106 "text": [
107 "Before anything else, let's make sure you can't lose your way in. πŸ”‘\n\n",
108 {
109 "if": "native",
110 "text": "Your access to this space lives in a key that exists only on this device β€” there's no username or password, and nobody can reset it for you. If you lose the device, your access goes with it.\n\n"
111 },
112 {
113 "if": "!native",
114 "text": "Your access to this space lives in a key that exists only in this browser β€” there's no username or password, and nobody can reset it for you. If this browser's data is cleared, your access goes with it.\n\n"
115 },
116 {
117 "if": "native",
118 "text": "Sign in with Eleven and your access is safe β€” it's saved to your account, and every device you sign in on can open this space."
119 },
120 {
121 "if": "!native",
122 "text": "Sign in with Eleven and your access is safe β€” one tap, your face or fingerprint, and you'll be brought straight back so we can carry on."
123 }
124 ]
125 }
126 ],
127 "chips": [
128 {
129 "label": "Sign in (recommended)",
130 "advancing": false,
131 "effect": {
132 "verb": "savePasskey"
133 },
134 "probe": {
135 "afterMs": 1500,
136 "unless": {
137 "any": [
138 "bridge.enrolled",
139 "bridge.homeSignedIn"
140 ]
141 },
142 "goto": "access-waiting"
143 }
144 },
145 {
146 "label": "Not now",
147 "spent": "Skipped",
148 "effect": {
149 "verb": "deferBackupReminders"
150 },
151 "record": {
152 "label": "Skipped signing in for now",
153 "value": "skipped"
154 },
155 "ack": "No problem β€” I'll nudge you again in a day or so.",
156 "goto": "name"
157 },
158 {
159 "label": "Fill in a form instead",
160 "trailing": true,
161 "advancing": false,
162 "effect": {
163 "verb": "openQuickForm"
164 }
165 }
166 ]
167 },
168 {
169 "id": "access-waiting",
170 "settle": {
171 "when": {
172 "any": [
173 "bridge.enrolled",
174 "bridge.homeSignedIn"
175 ]
176 },
177 "goto": "access"
178 },
179 "bubbles": [
180 {
181 "text": "I'll wait here while you finish signing in. When you're done, tap Continue."
182 }
183 ],
184 "chips": [
185 {
186 "label": "Continue",
187 "record": {
188 "step": "access",
189 "label": {
190 "if": {
191 "any": [
192 "bridge.enrolled",
193 "bridge.homeSignedIn"
194 ]
195 },
196 "then": "Signed in β€” your access is safe",
197 "else": "Signed in (in this browser)"
198 },
199 "value": "passkey"
200 },
201 "ack": "Perfect β€” you're all set. πŸ”’",
202 "goto": "name"
203 },
204 {
205 "label": "It didn't work β€” skip for now",
206 "spent": "Skipped",
207 "effect": {
208 "verb": "deferBackupReminders"
209 },
210 "record": {
211 "step": "access",
212 "label": "Skipped signing in for now",
213 "value": "skipped"
214 },
215 "ack": "No problem β€” I'll nudge you again in a day or so.",
216 "goto": "name"
217 }
218 ]
219 },
220 {
221 "id": "name",
222 "skipIf": [
223 "done",
224 "bridge.myName"
225 ],
226 "skipTo": "photo",
227 "bubbles": [
228 {
229 "text": "{ack?}First things first β€” what should folks here call you? Reply with your name.",
230 "key": "q-name",
231 "label": "Your name:",
232 "hint": "e.g. Finn Wolfhard"
233 }
234 ],
235 "chips": [
236 {
237 "if": "suggested",
238 "label": "I'm {suggested}",
239 "set": {
240 "vars.answer": "{suggested}"
241 },
242 "effect": {
243 "verb": "setMyName",
244 "args": [
245 "$answer"
246 ]
247 },
248 "record": {
249 "label": "noted: you're {vars.answer}",
250 "value": "$answer"
251 },
252 "ack": "Lovely to meet you, {vars.answer}! 🀝",
253 "goto": "photo"
254 }
255 ],
256 "input": {
257 "kind": "text",
258 "required": true,
259 "maxLen": 32,
260 "clean": "name",
261 "confirm": {
262 "when": "email",
263 "goto": "name-email"
264 }
265 },
266 "effect": {
267 "verb": "setMyName",
268 "args": [
269 "$answer"
270 ]
271 },
272 "on": {
273 "ok": {
274 "record": {
275 "label": "noted: you're {vars.answer}",
276 "value": "$answer"
277 },
278 "ack": "Lovely to meet you, {vars.answer}! 🀝",
279 "goto": "photo"
280 }
281 }
282 },
283 {
284 "id": "name-email",
285 "bubbles": [
286 {
287 "text": "That's an email address β€” is that what you'd like to be called here? It's the name everyone in this space sees.",
288 "key": "q-name-email"
289 }
290 ],
291 "chips": [
292 {
293 "label": "Use it anyway",
294 "spent": "Kept",
295 "effect": {
296 "verb": "setMyName",
297 "args": [
298 "$answer"
299 ]
300 },
301 "record": {
302 "step": "name",
303 "label": "noted: you're {vars.answer}",
304 "value": "$answer"
305 },
306 "ack": "Righto β€” {vars.answer} it is. 🀝",
307 "goto": "photo"
308 },
309 {
310 "label": "Type a different name",
311 "spent": "Changed",
312 "goto": "name"
313 }
314 ]
315 },
316 {
317 "id": "photo",
318 "skipIf": [
319 "done",
320 "native"
321 ],
322 "skipTo": "finish",
323 "bubbles": [
324 {
325 "text": "{ack?}Want to add a profile photo? Only members of this space can see it β€” like everything else here, it's encrypted.",
326 "key": "q-photo"
327 },
328 {
329 "text": "Send me a photo β€” tap the + next to the message box, or just drag a picture into the chat, and hit send. If you type a message with it, I'll keep that as the photo's description. Or skip for now.",
330 "attachHint": "Optional: describe your photo"
331 }
332 ],
333 "chips": [
334 {
335 "label": "Skip for now",
336 "spent": "Skipped",
337 "cancelInput": true,
338 "set": {
339 "vars.skippedPhoto": true
340 },
341 "record": {
342 "label": "skipped the profile photo",
343 "value": "skipped"
344 },
345 "goto": "finish"
346 }
347 ],
348 "input": {
349 "kind": "photo",
350 "reject": {
351 "text": "Send it as a picture β€” tap the + next to the message box or drag one in β€” or tap Skip.",
352 "local": true
353 }
354 },
355 "effect": {
356 "verb": "adoptProfilePhoto"
357 },
358 "on": {
359 "ok": {
360 "goto": "photo-preview"
361 },
362 "nokey": {
363 "say": "One sec β€” I'm still finishing your secure setup. Try sending it again in a moment, or skip for now.",
364 "local": true,
365 "ask": "Ready when you are β€” send that photo again, or skip it."
366 },
367 "error": {
368 "say": "Hmm, I couldn't use that one β€” try another?",
369 "local": true,
370 "ask": "Of course! Send me another one whenever you're ready β€” and pop a message with it if you'd like a description. πŸ“·"
371 }
372 }
373 },
374 {
375 "id": "photo-preview",
376 "bubbles": [
377 {
378 "text": "Here's how it looks. Happy with it, or want to try another?",
379 "img": "$myAvatar",
380 "imgAlt": "Your profile photo",
381 "imgRound": true,
382 "local": true
383 }
384 ],
385 "chips": [
386 {
387 "label": "Keep this photo",
388 "spent": "Kept",
389 "record": {
390 "step": "photo",
391 "label": "set your profile photo"
392 },
393 "goto": "finish"
394 },
395 {
396 "label": "Use a different photo",
397 "gotoAsk": {
398 "step": "photo",
399 "text": "Of course! Send me another one whenever you're ready β€” and pop a message with it if you'd like a description. πŸ“·"
400 }
401 }
402 ]
403 },
404 {
405 "id": "finish",
406 "record": {
407 "label": "You're all set",
408 "value": "done"
409 },
410 "effects": [
411 {
412 "verb": "markWelcomeDone"
413 }
414 ],
415 "bubbles": [
416 {
417 "text": [
418 {
419 "if": "vars.skippedPhoto",
420 "text": "No problem β€” you can add one anytime from your profile.\n\n"
421 },
422 "That's it β€” you're all set. πŸŽ‰ Enjoy {space.name|this space}!",
423 {
424 "if": "openGroups",
425 "text": "\n\nThis space also has open groups anyone here can join β€” have a look around whenever you like."
426 },
427 {
428 "if": {
429 "all": [
430 "!accessBackedUp",
431 "bridge.canEnrol"
432 ]
433 },
434 "text": "\n\nOne more reminder before you go: you haven't signed in yet, so your access to this space lives only in this browser β€” if it's cleared or lost, there's no way back in. Sign in any time and you're safe."
435 }
436 ],
437 "key": "q-finish"
438 },
439 {
440 "text": "Where would you like to start?"
441 }
442 ],
443 "chips": [
444 {
445 "if": {
446 "all": [
447 "!accessBackedUp",
448 "bridge.canEnrol"
449 ]
450 },
451 "label": "Sign in",
452 "advancing": false,
453 "effect": {
454 "verb": "savePasskey"
455 }
456 },
457 {
458 "if": {
459 "all": [
460 "hasPendingThread",
461 "inviterName"
462 ]
463 },
464 "label": "Say hi to {inviterName}",
465 "advancing": false,
466 "effect": {
467 "verb": "openPendingThread"
468 }
469 },
470 {
471 "if": {
472 "all": [
473 "hasPendingThread",
474 "!inviterName"
475 ]
476 },
477 "label": "Open your first chat",
478 "advancing": false,
479 "effect": {
480 "verb": "openPendingThread"
481 }
482 },
483 {
484 "if": "openGroups",
485 "label": "Browse open groups",
486 "advancing": false,
487 "effect": {
488 "verb": "openDiscover"
489 }
490 },
491 {
492 "if": "!native",
493 "label": "Take the tour",
494 "advancing": false,
495 "effect": {
496 "verb": "startTour"
497 }
498 },
499 {
500 "label": "Done for now",
501 "spent": "Done",
502 "say": "You're all set. πŸ‘ I'm here whenever you want me β€” just say hello, or type `/` to see what I can do."
503 }
504 ],
505 "end": true
506 }
507 ]
508}
509