Skip to content

Instantly share code, notes, and snippets.

@imbhargav5
Last active December 15, 2019 12:58
Show Gist options
  • Save imbhargav5/0a052eaeed19e2c7e415a676267aa340 to your computer and use it in GitHub Desktop.
Save imbhargav5/0a052eaeed19e2c7e415a676267aa340 to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
function randanimalSync(){
return "stuff"
}
function isSettings(context) {
return context.isSettings;
}
function onlyUserExists(context) {
return context.user && !context.user.name;
}
function userAccountInfoExists(context) {
return context.user && context.user.name;
}
function userAccountInfoExistsAndIsElectron(context) {
return context.user && context.user.name && context.isElectron;
}
function userAccountInfoAndGameInfoExists(context) {
return context.user && context.user.name && context.user.defaultSummoner;
}
function isSettingsAndUserAccountInfoAndGameInfoExists(context) {
return (
context.isSettings &&
context.user &&
context.user.name &&
context.user.defaultSummoner
);
}
function userLinkedAtLeastOneGame(context) {
return (
context.user && (context.user.defaultSummoner || context.user.fnAccount)
);
}
/**
* TODO: Make actions more readable and put them in the actions config
* TODO: Figure out how to avoid passing `user` across machines
* TODO: Figure out how to pass token into the userApi scope.
*/
const AccountMachine = Machine(
{
initial: 'init',
context: {
isSettings: false, // false by default , but can be set from the component
isElectron: null, // null => does'nt matter
forceEmailSend: false,
securityCode: null,
email: null,
token: null,
tokenExpiry: null,
user: null,
error: null,
},
states: {
init: {
on: {
'': [
{
target: 'display',
cond: isSettingsAndUserAccountInfoAndGameInfoExists,
},
{
target: 'loginComplete',
cond: userAccountInfoAndGameInfoExists,
},
{
target: 'linkGames',
cond: userAccountInfoExists,
},
{
target: 'accountInfo',
cond: onlyUserExists,
},
{
target: 'email',
},
],
},
},
display: {
id: 'display',
on: {
START_EDIT: 'accountInfo',
},
},
email: {
initial: 'input',
states: {
input: {
on: {
INPUT: {
target: 'input',
actions: 'commitEmail',
},
SUBMIT: {
target: 'verificationPending',
actions: 'createSecurityCode',
},
},
},
verificationPending: {
on: {
FORCE_SEND: {
target: 'input',
actions: ['setForceEmailSend'],
},
BACK: {
target: 'input',
},
SUCCESS: {
target: 'verificationSuccess',
actions: ['handleUserLogin'],
},
ERROR: 'verificationError',
},
},
verificationSuccess: {
after: {
3000: 'end',
},
},
verificationError: {},
end: {
type: 'final',
on: {
'': '#partialLogin',
},
},
},
},
partialLogin: {
id: 'partialLogin',
on: {
'': [
{
target: 'loginComplete',
cond: userAccountInfoAndGameInfoExists,
},
{
target: 'loginComplete',
cond: userAccountInfoExistsAndIsElectron,
},
{
target: 'linkGames',
cond: userAccountInfoExists,
},
{
target: 'accountInfo',
},
],
},
},
accountInfo: {
initial: 'idle',
states: {
idle: {
on: {
SAVE: {
target: 'saving',
},
},
},
saving: {
on: {
SAVED: {
target: '#linkGames',
actions: ['commitUser'],
},
SAVE_ERROR: 'save_error',
},
},
save_error: {
on: {
'': {
target: 'idle',
actions: 'commitError',
},
},
},
},
},
linkGames: {
id: 'linkGames',
type: 'parallel',
states: {
status: {
initial: 'check',
states: {
idle: {},
check: {
on: {
'': [
{
target: 'gamesLinked',
cond: userLinkedAtLeastOneGame,
},
{
target: 'idle',
},
],
},
},
gamesLinked: {
on: {
ENDED: 'end',
},
},
end: {
type: 'final',
on: {
'': '#loginComplete',
},
},
},
on: {
UPDATE_USER: {
target: '.check',
actions: ['commitUser'],
},
},
},
lolDetect: {
initial: "check",
states: {
check: {
on: {
'' : [
{
target: 'detectLoL',
cond: 'isElectronAndIsNotSettings'
},
{
target: 'disabled'
}
]
}
},
disabled: {
type: 'final'
},
detectLoL: {
on: {
"LOL_DETECTED": "summonerVerified",
},
after:{
15000: "summonerInput"
}
},
summonerInput: {
on: {
'SUMMONER_ADDED': 'summonerAdded'
}
},
summonerAdded: {
after:{
3000: 'summonerVerified'
}
},
summonerVerified: {
type: 'final',
}
}
}
}
},
loginComplete: {
id: 'loginComplete',
invoke: {
id: 'persist',
src: 'persist',
onDone: [
{
target: 'display',
cond: isSettings,
},
{
target: 'postLogin',
},
],
onError: 'init',
},
},
postLogin: {
type: 'final',
},
},
},
{
actions: {
commitUser: assign((context, event) => {
const { user } = event;
return {
...context,
user,
};
}),
commitToken: assign((context, event) => {
const { token } = event;
return {
...context,
token,
};
}),
commitEmail: assign((context, event) => {
return {
...context,
email: event.email,
};
}),
commitError: assign((context, event) => {
return {
...context,
error: event.error,
};
}),
createSecurityCode: assign(context => {
return {
...context,
securityCode: randanimalSync(),
};
}),
setForceEmailSend: assign(context => {
return {
...context,
forceEmailSend: true,
};
}),
handleUserLogin: assign((context, event) => {
// this is a hack.
// Remove it later
// it's not persisted because we don't want login process
// to leave anything on storage if the process isn't complete
window.__xstateToken = event.token;
return {
...context,
user: event.user,
token: event.token,
tokenExpiry: event.tokenExpiry,
region:
context.user &&
context.user.defaultSummoner &&
context.user.defaultSummoner.region
? context.user.defaultSummoner.region
: undefined,
};
}),
},
guards: {
isElectron: context => context.isElectron,
isElectronAndNotSettings : context => context.isElectron && !context.isSettings
},
}
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment