| 1 | { |
| 2 | "schema": 1, |
| 3 | "flow": "setup", |
| 4 | "entry": "hello", |
| 5 | "resumedIf": { |
| 6 | "any": [ |
| 7 | "done.name", |
| 8 | "done.group", |
| 9 | "done.email", |
| 10 | "done.photo", |
| 11 | "done.invites", |
| 12 | "done.extras", |
| 13 | "done.keys" |
| 14 | ] |
| 15 | }, |
| 16 | "resumeUnless": { |
| 17 | "all": [ |
| 18 | "bridge.enrolled", |
| 19 | "!done.keys" |
| 20 | ] |
| 21 | }, |
| 22 | "resumeSay": "Welcome back β let's pick up where we left off.", |
| 23 | "steps": [ |
| 24 | { |
| 25 | "id": "hello", |
| 26 | "skipIf": [ |
| 27 | "resumed" |
| 28 | ], |
| 29 | "bubbles": [ |
| 30 | { |
| 31 | "text": "Hi β I'm Eleven! π This is your space now: everything in it is end-to-end encrypted, and you're its administrator.\n\nLet's take two minutes to set things up." |
| 32 | } |
| 33 | ], |
| 34 | "auto": "name" |
| 35 | }, |
| 36 | { |
| 37 | "id": "name", |
| 38 | "entries": [ |
| 39 | { |
| 40 | "if": "bridge.myName", |
| 41 | "recordIfNew": { |
| 42 | "label": "noted the name you go by", |
| 43 | "value": "known" |
| 44 | }, |
| 45 | "goto": "group" |
| 46 | } |
| 47 | ], |
| 48 | "skipIf": [ |
| 49 | "done" |
| 50 | ], |
| 51 | "bubbles": [ |
| 52 | { |
| 53 | "text": "First β what should everyone here call you? Reply with your name.", |
| 54 | "label": "Your name:", |
| 55 | "hint": "e.g. Finn Wolfhard" |
| 56 | } |
| 57 | ], |
| 58 | "chips": [ |
| 59 | { |
| 60 | "label": "Fill in a form instead", |
| 61 | "trailing": true, |
| 62 | "advancing": false, |
| 63 | "effect": { |
| 64 | "verb": "openQuickForm" |
| 65 | } |
| 66 | } |
| 67 | ], |
| 68 | "input": { |
| 69 | "kind": "text", |
| 70 | "required": true, |
| 71 | "maxLen": 32, |
| 72 | "clean": "name" |
| 73 | }, |
| 74 | "effect": { |
| 75 | "verb": "setMyName", |
| 76 | "args": [ |
| 77 | "$answer" |
| 78 | ] |
| 79 | }, |
| 80 | "on": { |
| 81 | "ok": { |
| 82 | "record": { |
| 83 | "label": "noted: you're {vars.answer}", |
| 84 | "value": "$answer" |
| 85 | }, |
| 86 | "ack": "Lovely to meet you, {vars.answer}! π€", |
| 87 | "goto": "group" |
| 88 | } |
| 89 | } |
| 90 | }, |
| 91 | { |
| 92 | "id": "group", |
| 93 | "skipIf": [ |
| 94 | "done" |
| 95 | ], |
| 96 | "bubbles": [ |
| 97 | { |
| 98 | "text": "{ack?}Next, this space needs a name. It's the one everyone sees β on the sign-in page, in invites, on the app icon.", |
| 99 | "key": "q-group" |
| 100 | }, |
| 101 | { |
| 102 | "text": { |
| 103 | "if": "space.nameSet", |
| 104 | "then": "It's currently β{space.name}β β keep that, or reply with a new name.", |
| 105 | "else": "What should we call it? Reply with a name." |
| 106 | }, |
| 107 | "label": "Space name:", |
| 108 | "hint": "e.g. The Book Club" |
| 109 | } |
| 110 | ], |
| 111 | "chips": [ |
| 112 | { |
| 113 | "if": "space.nameSet", |
| 114 | "label": "Keep β{space.name}β", |
| 115 | "spent": "Kept", |
| 116 | "goto": "email" |
| 117 | } |
| 118 | ], |
| 119 | "input": { |
| 120 | "kind": "text", |
| 121 | "required": true |
| 122 | }, |
| 123 | "effect": { |
| 124 | "verb": "setGroupName", |
| 125 | "args": [ |
| 126 | "$answer" |
| 127 | ] |
| 128 | }, |
| 129 | "on": { |
| 130 | "ok": { |
| 131 | "set": { |
| 132 | "space.name": "$answer" |
| 133 | }, |
| 134 | "record": { |
| 135 | "label": "named this space β{vars.answer}β", |
| 136 | "value": "$answer" |
| 137 | }, |
| 138 | "goto": "email" |
| 139 | }, |
| 140 | "invalid": { |
| 141 | "say": "Hmm, that name didn't stick β it needs to be 1β60 characters. Try another?", |
| 142 | "retry": "step" |
| 143 | }, |
| 144 | "error": { |
| 145 | "say": "Something went wrong saving that β it's not the name's fault. Give it another go in a moment.", |
| 146 | "retry": "step" |
| 147 | } |
| 148 | } |
| 149 | }, |
| 150 | { |
| 151 | "id": "email", |
| 152 | "skipIf": [ |
| 153 | "done" |
| 154 | ], |
| 155 | "bubbles": [ |
| 156 | { |
| 157 | "text": "Your contact email is shared with members β useful if someone's locked out, or something needs a human. It's optional." |
| 158 | }, |
| 159 | { |
| 160 | "text": "How can people here reach you outside the chat? Reply with an email address, or skip it.", |
| 161 | "label": "Contact email:", |
| 162 | "hint": "e.g. finn@example.com" |
| 163 | } |
| 164 | ], |
| 165 | "chips": [ |
| 166 | { |
| 167 | "label": "Skip for now", |
| 168 | "spent": "Skipped", |
| 169 | "record": { |
| 170 | "label": "skipped the contact email", |
| 171 | "value": "skipped" |
| 172 | }, |
| 173 | "goto": "photo" |
| 174 | } |
| 175 | ], |
| 176 | "input": { |
| 177 | "kind": "text" |
| 178 | }, |
| 179 | "effect": { |
| 180 | "verb": "setContactEmail", |
| 181 | "args": [ |
| 182 | "$answer" |
| 183 | ] |
| 184 | }, |
| 185 | "on": { |
| 186 | "ok": { |
| 187 | "record": { |
| 188 | "label": "noted a contact email", |
| 189 | "value": "$answer" |
| 190 | }, |
| 191 | "goto": "photo" |
| 192 | }, |
| 193 | "invalid": { |
| 194 | "ask": "That doesn't look like an email address β try again, or skip it." |
| 195 | }, |
| 196 | "error": { |
| 197 | "ask": "Something went wrong saving that β try again in a moment, or skip it." |
| 198 | } |
| 199 | } |
| 200 | }, |
| 201 | { |
| 202 | "id": "photo", |
| 203 | "skipIf": [ |
| 204 | "done", |
| 205 | "native" |
| 206 | ], |
| 207 | "skipTo": "invites", |
| 208 | "bubbles": [ |
| 209 | { |
| 210 | "text": "Want to give this space a face? The photo shows on the welcome page and when people join β you can always change it later." |
| 211 | }, |
| 212 | { |
| 213 | "text": "Send me a photo β tap the + next to the message box, or just drag a picture into the chat, and hit send. Type a message with it if you want to include alt text.", |
| 214 | "attachHint": "Optional: type alt text for the photo" |
| 215 | } |
| 216 | ], |
| 217 | "chips": [ |
| 218 | { |
| 219 | "label": "Skip for now", |
| 220 | "spent": "Skipped", |
| 221 | "cancelInput": true, |
| 222 | "record": { |
| 223 | "label": "skipped the space photo", |
| 224 | "value": "skipped" |
| 225 | }, |
| 226 | "goto": "invites" |
| 227 | } |
| 228 | ], |
| 229 | "input": { |
| 230 | "kind": "photo", |
| 231 | "reject": { |
| 232 | "text": "Send it as a picture β tap the + next to the message box or drag one in β or tap Skip." |
| 233 | } |
| 234 | }, |
| 235 | "effect": { |
| 236 | "verb": "adoptServerPhoto" |
| 237 | }, |
| 238 | "on": { |
| 239 | "ok": { |
| 240 | "set": { |
| 241 | "vars.photoAlt": "$answerText" |
| 242 | }, |
| 243 | "goto": "photo-preview" |
| 244 | }, |
| 245 | "error": { |
| 246 | "say": "Hmm, I couldn't use that one β try another?", |
| 247 | "ask": "Send another photo when you're ready, or skip it." |
| 248 | } |
| 249 | } |
| 250 | }, |
| 251 | { |
| 252 | "id": "photo-preview", |
| 253 | "bubbles": [ |
| 254 | { |
| 255 | "text": [ |
| 256 | "Here's how it looks.", |
| 257 | { |
| 258 | "if": "vars.photoAlt", |
| 259 | "text": "\n\nIts alt text is the message you sent β β{vars.photoAlt}β β and like the photo itself it's PUBLIC: anyone with an invite link can see both." |
| 260 | }, |
| 261 | "\n\nHappy with it, or want to try another?" |
| 262 | ], |
| 263 | "img": "$serverAvatar", |
| 264 | "imgAlt": "{vars.photoAlt|The space photo}", |
| 265 | "local": true |
| 266 | } |
| 267 | ], |
| 268 | "chips": [ |
| 269 | { |
| 270 | "label": "Keep this photo", |
| 271 | "spent": "Kept", |
| 272 | "record": { |
| 273 | "step": "photo", |
| 274 | "label": "set the space photo", |
| 275 | "value": "{vars.photoAlt}" |
| 276 | }, |
| 277 | "goto": "invites" |
| 278 | }, |
| 279 | { |
| 280 | "label": "Use a different photo", |
| 281 | "gotoAsk": { |
| 282 | "step": "photo", |
| 283 | "text": "Of course! Send me another one whenever you're ready β and pop a message with it if you'd like alt text. π·" |
| 284 | } |
| 285 | } |
| 286 | ] |
| 287 | }, |
| 288 | { |
| 289 | "id": "invites", |
| 290 | "skipIf": [ |
| 291 | "done" |
| 292 | ], |
| 293 | "bubbles": [ |
| 294 | { |
| 295 | "text": "Who gets to bring people in? You can always invite people. The question is whether members can too, or whether new faces only arrive through you." |
| 296 | } |
| 297 | ], |
| 298 | "chips": [ |
| 299 | { |
| 300 | "label": "Members can invite people", |
| 301 | "effect": { |
| 302 | "verb": "setUserInvites", |
| 303 | "args": [ |
| 304 | true |
| 305 | ] |
| 306 | }, |
| 307 | "record": { |
| 308 | "label": "decided members can invite people", |
| 309 | "value": "members" |
| 310 | }, |
| 311 | "goto": "extras" |
| 312 | }, |
| 313 | { |
| 314 | "label": "Only me", |
| 315 | "effect": { |
| 316 | "verb": "setUserInvites", |
| 317 | "args": [ |
| 318 | false |
| 319 | ] |
| 320 | }, |
| 321 | "record": { |
| 322 | "label": "decided only the admin invites people", |
| 323 | "value": "admin only" |
| 324 | }, |
| 325 | "goto": "extras" |
| 326 | } |
| 327 | ] |
| 328 | }, |
| 329 | { |
| 330 | "id": "extras", |
| 331 | "skipIf": [ |
| 332 | "done" |
| 333 | ], |
| 334 | "skipTo": "ai-optin", |
| 335 | "entries": [ |
| 336 | { |
| 337 | "if": "done.extras-apps", |
| 338 | "recordIfNew": { |
| 339 | "label": "chose this space's extras", |
| 340 | "value": "chosen" |
| 341 | }, |
| 342 | "goto": "ai-optin" |
| 343 | } |
| 344 | ], |
| 345 | "bubbles": [ |
| 346 | { |
| 347 | "text": "Nearly there. Your space comes with a couple of extras:\n\nβ’ Bots β little helpers members can create for reminders and jobs.\nβ’ Apps β to-dos, polls, whiteboards, and a studio for building your own.\n\nEverything essential works with these off, and you can change your mind anytime in Admin." |
| 348 | } |
| 349 | ], |
| 350 | "chips": [ |
| 351 | { |
| 352 | "label": "Keep both on", |
| 353 | "spent": "Kept", |
| 354 | "record": { |
| 355 | "label": "kept bots and apps on", |
| 356 | "value": "all-on" |
| 357 | }, |
| 358 | "goto": "ai-optin" |
| 359 | }, |
| 360 | { |
| 361 | "label": "Let me choose", |
| 362 | "goto": "extras-bots" |
| 363 | } |
| 364 | ] |
| 365 | }, |
| 366 | { |
| 367 | "id": "extras-bots", |
| 368 | "skipIf": [ |
| 369 | "done" |
| 370 | ], |
| 371 | "bubbles": [ |
| 372 | { |
| 373 | "text": "Bots β helpers that live in chats and do jobs: reminders, summaries, little tools. Members can create their own." |
| 374 | } |
| 375 | ], |
| 376 | "chips": [ |
| 377 | { |
| 378 | "label": "Enable bots", |
| 379 | "effect": { |
| 380 | "verb": "setFeature", |
| 381 | "args": [ |
| 382 | "bots", |
| 383 | true |
| 384 | ] |
| 385 | }, |
| 386 | "record": { |
| 387 | "label": "enabled bots", |
| 388 | "value": "on" |
| 389 | }, |
| 390 | "goto": "extras-apps" |
| 391 | }, |
| 392 | { |
| 393 | "label": "No bots here", |
| 394 | "spent": "Off", |
| 395 | "effect": { |
| 396 | "verb": "setFeature", |
| 397 | "args": [ |
| 398 | "bots", |
| 399 | false |
| 400 | ] |
| 401 | }, |
| 402 | "record": { |
| 403 | "label": "switched bots off", |
| 404 | "value": "off" |
| 405 | }, |
| 406 | "goto": "extras-apps" |
| 407 | } |
| 408 | ] |
| 409 | }, |
| 410 | { |
| 411 | "id": "extras-apps", |
| 412 | "skipIf": [ |
| 413 | "done" |
| 414 | ], |
| 415 | "bubbles": [ |
| 416 | { |
| 417 | "text": "And apps β the built-in extras like to-dos, polls, and whiteboards, plus the App Studio where members build their own." |
| 418 | } |
| 419 | ], |
| 420 | "chips": [ |
| 421 | { |
| 422 | "label": "Enable apps", |
| 423 | "effect": { |
| 424 | "verb": "setFeature", |
| 425 | "args": [ |
| 426 | "apps", |
| 427 | true |
| 428 | ] |
| 429 | }, |
| 430 | "record": { |
| 431 | "label": "enabled apps", |
| 432 | "value": "on" |
| 433 | }, |
| 434 | "goto": "ai-optin" |
| 435 | }, |
| 436 | { |
| 437 | "label": "No apps here", |
| 438 | "spent": "Off", |
| 439 | "effect": { |
| 440 | "verb": "setFeature", |
| 441 | "args": [ |
| 442 | "apps", |
| 443 | false |
| 444 | ] |
| 445 | }, |
| 446 | "record": { |
| 447 | "label": "switched apps off", |
| 448 | "value": "off" |
| 449 | }, |
| 450 | "goto": "ai-optin" |
| 451 | } |
| 452 | ] |
| 453 | }, |
| 454 | { |
| 455 | "id": "ai-optin", |
| 456 | "skipIf": [ |
| 457 | "done" |
| 458 | ], |
| 459 | "bubbles": [ |
| 460 | { |
| 461 | "text": "Last choice β AI. Say yes and Eleven, the built-in helper, joins this space: members can ask it things in plain language and it answers, builds, and helps out.\n\nAn honest note before you decide: Eleven's AI runs on Eleven Messenger's machines, and it can read the chats it's invited to β that's what lets it help. It never sees chats it isn't in, and you can switch it off anytime in Admin." |
| 462 | } |
| 463 | ], |
| 464 | "chips": [ |
| 465 | { |
| 466 | "label": "Bring Eleven in", |
| 467 | "spent": "On", |
| 468 | "effect": { |
| 469 | "verb": "setFeature", |
| 470 | "args": [ |
| 471 | "ai", |
| 472 | true |
| 473 | ] |
| 474 | }, |
| 475 | "record": { |
| 476 | "label": "invited Eleven's AI in", |
| 477 | "value": "on" |
| 478 | }, |
| 479 | "goto": "plan" |
| 480 | }, |
| 481 | { |
| 482 | "label": "Not now", |
| 483 | "spent": "Off", |
| 484 | "effect": { |
| 485 | "verb": "setFeature", |
| 486 | "args": [ |
| 487 | "ai", |
| 488 | false |
| 489 | ] |
| 490 | }, |
| 491 | "record": { |
| 492 | "label": "kept AI off", |
| 493 | "value": "off" |
| 494 | }, |
| 495 | "goto": "plan" |
| 496 | } |
| 497 | ] |
| 498 | }, |
| 499 | { |
| 500 | "id": "plan", |
| 501 | "skipIf": [ |
| 502 | "done", |
| 503 | "native" |
| 504 | ], |
| 505 | "skipTo": "keys", |
| 506 | "entries": [ |
| 507 | { |
| 508 | "if": "!bridge.planPrices", |
| 509 | "goto": "keys" |
| 510 | } |
| 511 | ], |
| 512 | "bubbles": [ |
| 513 | { |
| 514 | "text": "One more question β who is this space for?\n\nEvery space starts free, and free is a real home β kept that way by the spaces that pay. If this one's for a team, a community, or family, there's a plan that backs it (and the free spaces too).", |
| 515 | "key": "q-plan" |
| 516 | } |
| 517 | ], |
| 518 | "chips": [ |
| 519 | { |
| 520 | "if": "bridge.planTeam", |
| 521 | "label": "A team", |
| 522 | "goto": "plan-team" |
| 523 | }, |
| 524 | { |
| 525 | "if": "bridge.planCommunity", |
| 526 | "label": "A community", |
| 527 | "goto": "plan-community" |
| 528 | }, |
| 529 | { |
| 530 | "if": "bridge.planFamily", |
| 531 | "label": "Family & friends", |
| 532 | "goto": "plan-family" |
| 533 | }, |
| 534 | { |
| 535 | "label": "Keep it free", |
| 536 | "spent": "Free", |
| 537 | "trailing": true, |
| 538 | "record": { |
| 539 | "label": "kept this space free", |
| 540 | "value": "free" |
| 541 | }, |
| 542 | "goto": "keys" |
| 543 | } |
| 544 | ] |
| 545 | }, |
| 546 | { |
| 547 | "id": "plan-team", |
| 548 | "bubbles": [ |
| 549 | { |
| 550 | "text": "For a team that's {bridge.planNameTeam}: {bridge.planPriceTeam} β it scales with the team, and bots are free.\n\nA paid space never counts against your space limit, is never reclaimed as unused, and carries a bigger storage allowance.", |
| 551 | "key": "q-plan-team" |
| 552 | } |
| 553 | ], |
| 554 | "chips": [ |
| 555 | { |
| 556 | "label": "Choose {bridge.planNameTeam}", |
| 557 | "spent": "Chosen", |
| 558 | "set": { |
| 559 | "vars.planTier": "team" |
| 560 | }, |
| 561 | "record": { |
| 562 | "step": "plan", |
| 563 | "label": "chose the {bridge.planNameTeam} plan β payment waits at the finish line", |
| 564 | "value": "team" |
| 565 | }, |
| 566 | "goto": "keys" |
| 567 | }, |
| 568 | { |
| 569 | "label": "Keep it free", |
| 570 | "spent": "Free", |
| 571 | "record": { |
| 572 | "step": "plan", |
| 573 | "label": "kept this space free", |
| 574 | "value": "free" |
| 575 | }, |
| 576 | "goto": "keys" |
| 577 | } |
| 578 | ] |
| 579 | }, |
| 580 | { |
| 581 | "id": "plan-community", |
| 582 | "bubbles": [ |
| 583 | { |
| 584 | "text": "For a community that's {bridge.planNameCommunity}: {bridge.planPriceCommunity}.\n\nA paid space never counts against your space limit, is never reclaimed as unused, and carries a bigger storage allowance.", |
| 585 | "key": "q-plan-community" |
| 586 | } |
| 587 | ], |
| 588 | "chips": [ |
| 589 | { |
| 590 | "label": "Choose {bridge.planNameCommunity}", |
| 591 | "spent": "Chosen", |
| 592 | "set": { |
| 593 | "vars.planTier": "community" |
| 594 | }, |
| 595 | "record": { |
| 596 | "step": "plan", |
| 597 | "label": "chose the {bridge.planNameCommunity} plan β payment waits at the finish line", |
| 598 | "value": "community" |
| 599 | }, |
| 600 | "goto": "keys" |
| 601 | }, |
| 602 | { |
| 603 | "label": "Keep it free", |
| 604 | "spent": "Free", |
| 605 | "record": { |
| 606 | "step": "plan", |
| 607 | "label": "kept this space free", |
| 608 | "value": "free" |
| 609 | }, |
| 610 | "goto": "keys" |
| 611 | } |
| 612 | ] |
| 613 | }, |
| 614 | { |
| 615 | "id": "plan-family", |
| 616 | "bubbles": [ |
| 617 | { |
| 618 | "text": "For family and friends that's {bridge.planNameFamily}: {bridge.planPriceFamily}.\n\nA paid space never counts against your space limit, is never reclaimed as unused, and carries a bigger storage allowance.", |
| 619 | "key": "q-plan-family" |
| 620 | } |
| 621 | ], |
| 622 | "chips": [ |
| 623 | { |
| 624 | "label": "Choose {bridge.planNameFamily}", |
| 625 | "spent": "Chosen", |
| 626 | "set": { |
| 627 | "vars.planTier": "family" |
| 628 | }, |
| 629 | "record": { |
| 630 | "step": "plan", |
| 631 | "label": "chose the {bridge.planNameFamily} plan β payment waits at the finish line", |
| 632 | "value": "family" |
| 633 | }, |
| 634 | "goto": "keys" |
| 635 | }, |
| 636 | { |
| 637 | "label": "Keep it free", |
| 638 | "spent": "Free", |
| 639 | "record": { |
| 640 | "step": "plan", |
| 641 | "label": "kept this space free", |
| 642 | "value": "free" |
| 643 | }, |
| 644 | "goto": "keys" |
| 645 | } |
| 646 | ] |
| 647 | }, |
| 648 | { |
| 649 | "id": "keys", |
| 650 | "entries": [ |
| 651 | { |
| 652 | "if": "native", |
| 653 | "set": { |
| 654 | "vars.backedUp": true |
| 655 | }, |
| 656 | "recordIfNew": { |
| 657 | "label": "Your space's key is saved with your Eleven account", |
| 658 | "value": "native" |
| 659 | }, |
| 660 | "goto": "finish" |
| 661 | }, |
| 662 | { |
| 663 | "if": "bridge.enrolled", |
| 664 | "set": { |
| 665 | "vars.backedUp": true |
| 666 | }, |
| 667 | "recordIfNew": { |
| 668 | "label": "Signed in β your space's key is safe", |
| 669 | "value": "passkey" |
| 670 | }, |
| 671 | "sayIfNew": "You're signed in β your space's key is safe. β
", |
| 672 | "goto": "finish" |
| 673 | }, |
| 674 | { |
| 675 | "if": "done", |
| 676 | "goto": "finish" |
| 677 | }, |
| 678 | { |
| 679 | "if": "!bridge.canEnrol", |
| 680 | "recordIfNew": { |
| 681 | "label": "This browser holds this space's key", |
| 682 | "value": "local" |
| 683 | }, |
| 684 | "goto": "finish" |
| 685 | }, |
| 686 | { |
| 687 | "if": "bridge.fromHome", |
| 688 | "goto": "keys-home" |
| 689 | } |
| 690 | ], |
| 691 | "settle": { |
| 692 | "when": "bridge.enrolled" |
| 693 | }, |
| 694 | "bubbles": [ |
| 695 | { |
| 696 | "text": "Now the most important thing of all. π\n\nEverything here is locked with a key that exists only on your devices. There's no password reset and no support desk β not even whoever runs the server can read your messages or recover that key. That's not a flaw; it's the whole point.\n\nBut it means: right now, this browser holds the only key to your space. If it's lost β cleared, broken, stolen β your space is gone with it, and nobody can get it back." |
| 697 | }, |
| 698 | { |
| 699 | "text": "Sign in with Eleven and your key stays safe β one tap, your face or fingerprint, and you'll be brought straight back." |
| 700 | } |
| 701 | ], |
| 702 | "chips": [ |
| 703 | { |
| 704 | "label": "Sign in", |
| 705 | "advancing": false, |
| 706 | "effect": { |
| 707 | "verb": "savePasskey" |
| 708 | }, |
| 709 | "probe": { |
| 710 | "afterMs": 1500, |
| 711 | "unless": "bridge.enrolled", |
| 712 | "goto": "keys-waiting" |
| 713 | } |
| 714 | }, |
| 715 | { |
| 716 | "label": "Not now", |
| 717 | "spent": "Skipped", |
| 718 | "goto": "keys-confirm" |
| 719 | } |
| 720 | ] |
| 721 | }, |
| 722 | { |
| 723 | "id": "keys-home", |
| 724 | "entries": [ |
| 725 | { |
| 726 | "if": "bridge.enrolled", |
| 727 | "set": { |
| 728 | "vars.backedUp": true |
| 729 | }, |
| 730 | "recordIfNew": { |
| 731 | "label": "Signed in β your space's key is safe", |
| 732 | "value": "passkey" |
| 733 | }, |
| 734 | "sayIfNew": "You're signed in β your space's key is safe. β
", |
| 735 | "goto": "finish" |
| 736 | } |
| 737 | ], |
| 738 | "settle": { |
| 739 | "when": "bridge.enrolled" |
| 740 | }, |
| 741 | "bubbles": [ |
| 742 | { |
| 743 | "text": "Last thing β the key. π\n\nThis space is locked with a key that was just created here, in this browser. Your Eleven sign-in doesn't hold it yet β so if this browser is lost, the space goes with it." |
| 744 | }, |
| 745 | { |
| 746 | "text": "Sign in and it's added to your account β one tap, and you'll be brought straight back." |
| 747 | } |
| 748 | ], |
| 749 | "chips": [ |
| 750 | { |
| 751 | "label": "Sign in", |
| 752 | "advancing": false, |
| 753 | "effect": { |
| 754 | "verb": "savePasskey" |
| 755 | }, |
| 756 | "probe": { |
| 757 | "afterMs": 1500, |
| 758 | "unless": "bridge.enrolled", |
| 759 | "goto": "keys-waiting" |
| 760 | } |
| 761 | }, |
| 762 | { |
| 763 | "label": "Not now", |
| 764 | "spent": "Skipped", |
| 765 | "goto": "keys-confirm" |
| 766 | } |
| 767 | ] |
| 768 | }, |
| 769 | { |
| 770 | "id": "keys-waiting", |
| 771 | "settle": { |
| 772 | "when": "bridge.enrolled", |
| 773 | "goto": "keys" |
| 774 | }, |
| 775 | "bubbles": [ |
| 776 | { |
| 777 | "text": "I'll wait here while you finish signing in. When you're done, tap Continue." |
| 778 | } |
| 779 | ], |
| 780 | "chips": [ |
| 781 | { |
| 782 | "label": "Continue", |
| 783 | "record": { |
| 784 | "step": "keys", |
| 785 | "label": { |
| 786 | "if": "bridge.enrolled", |
| 787 | "then": "Signed in β your space's key is safe", |
| 788 | "else": "Signed in (in this browser)" |
| 789 | }, |
| 790 | "value": "passkey" |
| 791 | }, |
| 792 | "set": { |
| 793 | "vars.backedUp": true |
| 794 | }, |
| 795 | "goto": "finish" |
| 796 | }, |
| 797 | { |
| 798 | "label": "It didn't work β skip for now", |
| 799 | "spent": "Skipped", |
| 800 | "record": { |
| 801 | "step": "keys", |
| 802 | "label": "Skipped signing in for now", |
| 803 | "value": "skipped" |
| 804 | }, |
| 805 | "set": { |
| 806 | "vars.backedUp": false |
| 807 | }, |
| 808 | "goto": "finish" |
| 809 | } |
| 810 | ] |
| 811 | }, |
| 812 | { |
| 813 | "id": "keys-confirm", |
| 814 | "settle": { |
| 815 | "when": "bridge.enrolled", |
| 816 | "goto": "keys" |
| 817 | }, |
| 818 | "bubbles": [ |
| 819 | { |
| 820 | "text": "I have to be straight with you: if you don't sign in, one lost or cleared browser means this space and everything in it is gone β permanently, for everyone, and no one can help. I'll remind you again in a day or so." |
| 821 | } |
| 822 | ], |
| 823 | "chips": [ |
| 824 | { |
| 825 | "label": "Go back and sign in", |
| 826 | "advancing": false, |
| 827 | "effect": { |
| 828 | "verb": "savePasskey" |
| 829 | }, |
| 830 | "probe": { |
| 831 | "afterMs": 1500, |
| 832 | "unless": "bridge.enrolled", |
| 833 | "goto": "keys-waiting" |
| 834 | } |
| 835 | }, |
| 836 | { |
| 837 | "label": "I understand the risk", |
| 838 | "spent": "Understood", |
| 839 | "record": { |
| 840 | "step": "keys", |
| 841 | "label": "Skipped signing in for now", |
| 842 | "value": "skipped" |
| 843 | }, |
| 844 | "set": { |
| 845 | "vars.backedUp": false |
| 846 | }, |
| 847 | "goto": "finish" |
| 848 | } |
| 849 | ] |
| 850 | }, |
| 851 | { |
| 852 | "id": "finish", |
| 853 | "record": { |
| 854 | "label": "Your space is ready", |
| 855 | "value": "done" |
| 856 | }, |
| 857 | "effects": [ |
| 858 | { |
| 859 | "if": "!vars.backedUp", |
| 860 | "verb": "deferBackupReminders" |
| 861 | }, |
| 862 | { |
| 863 | "verb": "markSetupComplete" |
| 864 | } |
| 865 | ], |
| 866 | "bubbles": [ |
| 867 | { |
| 868 | "text": [ |
| 869 | "That's it β {space.name|your space} is ready! π\n\n", |
| 870 | "Everything we just set up lives in your Admin panel β invite links, the space's name and photo, who can invite. Type `/admin` anywhere to open it; it's yours alone as this space's admin.", |
| 871 | { |
| 872 | "if": { |
| 873 | "all": [ |
| 874 | "!vars.backedUp", |
| 875 | "bridge.canEnrol" |
| 876 | ] |
| 877 | }, |
| 878 | "text": "\n\nOne more reminder before you go: you haven't signed in, so this browser holds the only key to this space. If it's lost or cleared, the space is gone with it β for everyone. Sign in any time and it's safe." |
| 879 | }, |
| 880 | { |
| 881 | "if": "vars.planTier", |
| 882 | "text": "\n\nAnd the plan you picked β tap below whenever you're ready to set up the payment. Your space runs free until then." |
| 883 | } |
| 884 | ], |
| 885 | "key": "q-finish" |
| 886 | }, |
| 887 | { |
| 888 | "text": "Where would you like to start?" |
| 889 | } |
| 890 | ], |
| 891 | "chips": [ |
| 892 | { |
| 893 | "if": { |
| 894 | "all": [ |
| 895 | "!vars.backedUp", |
| 896 | "bridge.canEnrol" |
| 897 | ] |
| 898 | }, |
| 899 | "label": "Sign in", |
| 900 | "advancing": false, |
| 901 | "effect": { |
| 902 | "verb": "savePasskey" |
| 903 | } |
| 904 | }, |
| 905 | { |
| 906 | "if": "vars.planTier", |
| 907 | "label": "Set up your plan", |
| 908 | "advancing": false, |
| 909 | "effect": { |
| 910 | "verb": "openPlanCheckout" |
| 911 | } |
| 912 | }, |
| 913 | { |
| 914 | "label": "Open admin", |
| 915 | "advancing": false, |
| 916 | "effect": { |
| 917 | "verb": "openAdmin" |
| 918 | } |
| 919 | }, |
| 920 | { |
| 921 | "if": "!native", |
| 922 | "label": "Take the tour", |
| 923 | "advancing": false, |
| 924 | "effect": { |
| 925 | "verb": "startTour" |
| 926 | } |
| 927 | } |
| 928 | ], |
| 929 | "end": true |
| 930 | } |
| 931 | ] |
| 932 | } |
| 933 | |