Skip to content

Instantly share code, notes, and snippets.

@robertpenner
Created June 21, 2021 06:43
Show Gist options
  • Save robertpenner/f7bcf0d5637ddbb70b05c5820749e7fd to your computer and use it in GitHub Desktop.
Save robertpenner/f7bcf0d5637ddbb70b05c5820749e7fd to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
const EMPTY_SONG = Object.freeze({
id: '',
title: '',
description: '',
thumbnail: '',
});
const context = {
// TODO: separate machines for logged in/logged out
// logged out
email: '',
password: '',
passwordA: '',
passwordB: '',
username: '',
loginError: '',
recoveryEmailError: '',
// logged in
player: {
song: EMPTY_SONG,
},
};
const audacyLoginState = {
id: 'Audacy login',
onDone: 'done login',
on: {
BACK: 'choosing login method',
},
// TODO: parallel states for email and password fields
initial: 'email',
states: {
email: {
onDone: 'password',
// on: {
// BACK: '#choosing login method',
// },
initial: 'entering email',
states: {
'entering email': {
on: {
'EDIT EMAIL': {
actions: 'assign email',
},
'SUBMIT EMAIL': {
target: 'checking email',
cond: 'email is valid',
},
},
},
'checking email': {
entry: 'clear login error',
invoke: {
src: 'check email',
onDone: [
{
target: '#creating account',
actions: 'clear login error',
cond: (_, { data }) => data === 'CREATE ACCOUNT',
},
{
target: 'done email',
actions: 'clear login error',
},
],
onError: {
target: 'entering email',
actions: 'assign login error',
},
},
},
'done email': { type: 'final' },
},
},
password: {
onDone: 'done Audacy login',
on: {
BACK: 'email',
},
initial: 'entering password',
states: {
'entering password': {
on: {
'EDIT PASSWORD': {
actions: 'assign password',
},
'FORGOT PASSWORD': '#resetting Audacy password',
'SUBMIT PASSWORD': {
target: 'checking password',
cond: 'password is valid',
},
},
},
'checking password': {
invoke: {
src: 'check password',
onDone: {
target: 'done password',
actions: 'clear login error',
},
onError: {
target: 'entering password',
actions: 'assign login error',
},
},
},
'done password': { type: 'final' },
},
},
'done Audacy login': { type: 'final' },
history: { type: 'history', history: 'deep' },
},
};
const loggedOutState = {
onDone: {
target: 'logged in',
},
initial: 'splash screen',
states: {
'splash screen': {
after: {
1000: 'choosing login method',
},
},
'choosing login method': {
id: 'choosing login method',
on: {
'CONTINUE WITH AUDACY': 'Audacy login',
},
},
'Audacy login': audacyLoginState,
'resetting Audacy password': {
id: 'resetting Audacy password',
onDone: 'Audacy login',
on: {
BACK: 'Audacy login.history',
},
initial: 'entering email',
states: {
'entering email': {
onDone: 'email sent',
initial: 'editing email',
states: {
'editing email': {
on: {
'SUBMIT EMAIL': 'sending recovery email',
},
},
'sending recovery email': {
invoke: {
src: 'send recovery email',
onDone: {
target: 'done entering email',
actions: 'clear recovery email error',
},
onError: {
target: 'editing email',
actions: 'assign recovery email error',
},
},
},
'done entering email': { type: 'final' },
},
},
'email sent': {
on: {
'RESEND EMAIL': 'entering email.sending recovery email',
'BACK TO LOGIN': 'done resetting Audacy password',
},
},
'done resetting Audacy password': { type: 'final' },
},
},
'creating account': {
id: 'creating account',
onDone: 'done login',
initial: 'choosing username',
states: {
'choosing username': {
on: {
BACK: '#Audacy login',
'EDIT USERNAME': {
actions: 'assign username',
},
'SUBMIT USERNAME': 'choosing password',
},
},
'choosing password': {
id: 'choosing password',
on: {
BACK: 'choosing username',
'EDIT PASSWORD A': {
actions: ['assign password A'],
},
'EDIT PASSWORD B': {
actions: ['assign password B'],
},
'SUBMIT NEW PASSWORD': {
target: 'submitting new password',
cond: 'passwords match',
},
},
},
'submitting new password': {
invoke: {
src: 'submit new password',
onDone: 'done creating account',
// TODO: assign error
onError: 'choosing password',
},
},
'done creating account': { type: 'final' },
},
},
'done login': { type: 'final' },
},
};
const loggedInState = {
id: 'logged in',
exit: 'clear email & password',
on: {
'LOG OUT': 'logged out',
},
type: 'parallel',
states: {
'core page': {
id: 'core page',
meta: { description: '4 pages with dedicated buttons' },
on: {
'FOR YOU': '.For you',
MUSIC: '.Music',
'NEWS & TALK': '.News & Talk',
FAVORITES: '.Favorites',
'PLAY SONG': {
actions: [
'assign song to player',
send('PLAY'),
send('MAXIMIZE PLAYER'),
],
},
},
initial: 'For you',
states: {
'For you': {},
Music: {},
'News & Talk': {},
Favorites: {},
},
},
'search page': {
id: 'search page',
meta: { description: 'stacks on top of core page & player' },
type: 'parallel',
states: {
visibility: {
initial: 'hidden',
states: {
hidden: {
on: {
SEARCH: 'visible',
},
},
visible: {
on: {
BACK: 'hidden',
},
},
},
},
referrer: {
on: {
'FOR YOU': '.For you',
MUSIC: '.Music',
'NEWS & TALK': '.News & Talk',
},
initial: 'For you',
states: {
'For you': {},
Music: {},
'News & Talk': {},
},
},
},
},
'settings page': {
id: 'settings page',
meta: { description: 'stacks on top of core page & player' },
type: 'parallel',
states: {
visibility: {
initial: 'hidden',
states: {
hidden: {
on: {
SETTINGS: 'visible',
},
},
visible: {
on: {
BACK: 'hidden',
},
},
},
},
avatar: {
initial: 'none',
states: {
none: {
on: { 'EDIT AVATAR': 'choosing avatar' },
},
'choosing avatar': {
on: { 'SAVE AVATAR': 'visible' },
},
visible: {
on: { 'EDIT AVATAR': 'choosing avatar' },
},
},
},
},
},
'content player': {
id: 'content player',
meta: { description: 'stacks on top of core page' },
type: 'parallel',
states: {
size: {
initial: 'minimized',
states: {
maximized: {
on: { 'MINIMIZE PLAYER': 'minimized' },
},
minimized: {
on: { 'MAXIMIZE PLAYER': 'maximized' },
},
},
},
playback: {
on: {
PLAY: '.playing',
STOP: '.stopped',
},
initial: 'stopped',
states: {
stopped: {},
playing: {
on: {
PAUSE: 'paused',
},
},
paused: {
on: {
PAUSE: 'playing',
},
},
},
},
},
},
},
};
const machine = Machine({
id: 'Audacy App',
// TODO: resolve this type error
// @ts-ignore
context,
initial: 'logged out',
states: {
'logged out': loggedOutState,
'logged in': loggedInState,
},
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment