Skip to content

Instantly share code, notes, and snippets.

@tmikeschu
Created March 26, 2020 21:04
Show Gist options
  • Save tmikeschu/81af144fbf0c8a244c4e4d1d50fc2467 to your computer and use it in GitHub Desktop.
Save tmikeschu/81af144fbf0c8a244c4e4d1d50fc2467 to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
const DATES_TAB = {
target: "dates",
actions: ["sendGAEvent"],
}
Machine({
id: "app",
initial: "fetchAttendee",
context: {
lastScreen: "schedule",
friendId: undefined,
friendTimeId: undefined,
someoneNewTimes: new Set(),
someoneNewInterests: new Set(),
attendee: null,
meetings: [],
apiBaseUrl: "",
token: "",
pendingMatchesCount: 0,
meetingId: undefined,
attendees: [],
newMeetings: false,
meetingTimes: [],
topics: [],
markMeetingsAsSeen: false,
},
entry: ["setBaseUrl", "setToken"],
states: {
fetchAttendee: {
invoke: {
id: "fetchAttendee",
src: "fetchAttendee",
onDone: {
target: "fetchMeetings",
actions: ["setAttendee", "setGADimension"],
},
onError: {
actions: () => {
throw new Error("Unable to fetch attendee")
},
},
},
},
fetchMeetings: {
on: { CONCAT_MEETINGS: { actions: ["concatMeetings"] } },
invoke: {
id: "meetingsApiMachine",
src: "meetingsApiMachine",
onDone: { target: "codeOfConduct" },
},
},
codeOfConduct: {
on: {
"": { target: "schedule", cond: "hasAcceptedCodeOfConduct" },
ACCEPT_CODE_OF_CONDUCT: {
target: "schedule",
cond: "hasAcceptedCodeOfConduct",
actions: ["sendGAEvent"],
},
},
},
schedule: {
id: "schedule",
initial: "home",
after: {
300: {
actions: ["setLastToSchedule"],
},
},
on: {
DATES_TAB,
SCHEDULE_TAB: "schedule",
SETTINGS: "settings",
},
states: {
hist: { type: "history", history: "deep" },
home: {
entry: ["clearState", "sendGAPageView"],
on: {
FRIEND: "friend",
SOMEONE_NEW: "someoneNew",
},
},
friend: {
initial: "fetchAttendees",
entry: "sendGAPageView",
states: {
fetchAttendees: {
invoke: {
id: "fetchAttendees",
src: "fetchAttendees",
onDone: {
target: "person",
actions: assign({ attendees: (_, event) => event.data }),
},
},
},
person: {
on: {
SELECT_FRIEND: { actions: ["setSelectedFriend"] },
TIME: {
target: "fetchTimes",
cond: "friendSelected",
actions: ["sendGAEvent"],
},
},
},
fetchTimes: {
invoke: {
id: "fetchTimes",
src: "fetchTimes",
onDone: { target: "time", actions: ["setMeetingTimes"] },
},
},
time: {
on: {
SELECT_TIME: {
actions: ["setSelectedFriendTime", "sendGAEvent"],
},
RESERVE_FRIEND: {
target: "reserve",
cond: "friendTimeSelected",
actions: ["sendGAEvent"],
},
},
},
reserve: {
invoke: {
id: "reserveFriend",
src: "reserveFriend",
onDone: { target: "reserved", actions: "addMeeting" },
},
},
reserved: {
entry: ["sendGAPageView"],
on: {
SCHEDULE_BUTTON: {
target: "#schedule",
actions: ["sendGAEvent"],
},
DATES_BUTTON: {
target: "#dates",
actions: ["sendGAEvent"],
},
"": {
target: "#schedule.home",
cond: "datesToReserved",
},
},
},
},
},
someoneNew: {
entry: ["sendGAPageView"],
initial: "fetchTimes",
states: {
fetchTimes: {
invoke: {
id: "fetchTimes",
src: "fetchTimes",
onDone: { target: "times", actions: ["setMeetingTimes"] },
},
},
times: {
on: {
INTERESTS: {
target: "fetchTopics",
cond: "someoneNewTimesSelected",
actions: ["sendGAEvent"],
},
SELECT_SOMEONE_NEW_TIME: {
actions: ["setSelectedSomeoneNewTimes", "sendGAEvent"],
},
},
},
fetchTopics: {
invoke: {
id: "fetchTopics",
src: "fetchTopics",
onDone: { target: "interests", actions: ["setTopics"] },
},
},
interests: {
on: {
RESERVE_SOMEONE_NEW: {
target: "reserve",
actions: ["sendGAEvent"],
},
SELECT_SOMEONE_NEW_INTEREST: {
actions: ["setSelectedSomeoneNewInterests", "sendGAEvent"],
},
},
},
reserve: {
invoke: {
id: "reserveSomeoneNew",
src: "reserveSomeoneNew",
onDone: [
{
target: "reservedInstant",
actions: ["addMeeting", "setSelectedFriend"],
cond: "instantMatch",
},
{ target: "reservedMagic", actions: ["addMeeting"] },
],
},
},
reservedMagic: {
entry: ["sendGAPageView"],
on: {
SCHEDULE_BUTTON: {
target: "#schedule",
actions: ["sendGAEvent"],
},
DATES_BUTTON: {
target: "#dates",
actions: ["sendGAEvent"],
},
"": {
target: "#schedule.home",
cond: "datesToReserved",
},
},
},
reservedInstant: {
entry: ["sendGAPageView"],
on: {
SCHEDULE_BUTTON: {
target: "#schedule",
actions: ["sendGAEvent"],
},
DATES_BUTTON: {
target: "#dates",
actions: ["sendGAEvent"],
},
"": {
target: "#schedule.home",
cond: "datesToReserved",
},
},
},
},
},
},
},
dates: {
id: "dates",
initial: "home",
after: {
300: { actions: ["setLastToDates"] },
},
on: {
CONCAT_MEETINGS: { actions: ["concatMeetings"] },
SET_PENDING_MATCHES: {
actions: assign({
pendingMatchesCount: ({ pendingMatchesCount }, event) =>
event.type === "SET_PENDING_MATCHES"
? event.data
: pendingMatchesCount,
}),
},
SCHEDULE_TAB: "schedule.hist",
DATES_TAB,
SETTINGS: "settings",
SET_MEETING_ID: {
actions: assign({
meetingId: ({ meetingId }, event) =>
event.type === "SET_MEETING_ID" ? event.data : meetingId,
}),
},
},
states: {
hist: { type: "history", history: "deep" },
home: {
initial: "init",
entry: ["sendGAPageView"],
on: {
DECLINE: {
target: "decline",
actions: ["sendGAEvent"],
},
CANCEL: {
target: "cancel",
actions: ["sendGAEvent"],
},
DISMISS: {
target: "dismissMeeting",
actions: ["sendGAEvent"],
},
},
invoke: {
id: "meetingsApiMachine",
src: "meetingsApiMachine",
data: ({ attendee, graphqlClient }) => ({
attendee,
graphqlClient,
}),
},
states: {
init: {
after: {
2000: "seen",
},
},
seen: {
exit: ["setMeetingsSeen"],
invoke: {
id: "markMeetingsSeen",
src: "markMeetingsSeen",
onDone: { actions: ["queueMeetingsForMarkedAsSeen"] },
},
},
},
},
dismissMeeting: {
invoke: {
id: "dismissMeeting",
src: "dismissMeeting",
onDone: {
target: "home",
actions: assign({
meetings: ({ meetings }, event) => {
return meetings.filter(m => m.uuid !== event.data.uuid)
},
}),
},
},
},
decline: {
initial: "confirm",
states: {
confirm: {
entry: ["sendGAPageView"],
on: {
DECLINE_CONFIRM: {
target: "declineMeeting",
actions: ["sendGAEvent"],
},
CANCEL: {
target: "#dates",
actions: ["sendGAEvent"],
},
},
},
declineMeeting: {
invoke: {
id: "declineMeeting",
src: "declineMeeting",
onDone: { target: "reason", actions: ["setMeeting"] },
},
},
reason: {
on: {
NOT_AVAILABLE: {
target: "becauseNotAvailable",
actions: ["sendGAEvent"],
},
NOT_INTERESTED: {
target: "becauseNotInterested",
actions: ["sendGAEvent"],
},
},
},
becauseNotAvailable: {
invoke: {
id: "becauseNotInterested",
src: "updateRejection",
onDone: {
target: "notAvailable",
actions: ["setMeeting"],
},
},
},
becauseNotInterested: {
invoke: {
id: "becauseNotInterested",
src: "updateRejection",
onDone: {
target: "notInterested",
actions: ["setMeeting"],
},
},
},
notAvailable: {
entry: ["sendGAPageView"],
on: {
DATES_BUTTON: {
target: "#dates",
},
SCHEDULE_BUTTON: {
target: "#schedule",
actions: ["sendGAEvent"],
},
},
},
notInterested: {
entry: "sendGAPageView",
on: {
DATES_BUTTON: {
target: "#dates",
},
SCHEDULE_BUTTON: {
target: "#schedule",
actions: "sendGAEvent",
},
},
},
},
},
cancel: {
initial: "confirm",
states: {
confirm: {
entry: "sendGAPageView",
on: {
DECLINE_CONFIRM: {
target: "declineMeeting",
actions: "sendGAEvent",
},
CANCEL: {
target: "#dates",
actions: "sendGAEvent",
},
},
},
declineMeeting: {
invoke: {
id: "declineMeeting",
src: "declineMeeting",
onDone: { target: "declined", actions: ["setMeeting"] },
},
},
declined: {
on: {
SCHEDULE_BUTTON: {
target: "#schedule",
actions: "sendGAEvent",
},
DATES_BUTTON: "#dates",
},
},
},
},
},
},
settings: {
initial: "home",
entry: "sendGAPageView",
exit: "sendGAEvent",
on: {
CLOSE: [
{ target: "schedule..hist", cond: "wasSchedule" },
{ target: "dates.hist", cond: "wasDates" },
{ target: "schedule" },
],
},
states: {
home: {
on: {
TOGGLE_ALLOW_MEETINGS: {
target: "toggleAllowMeetings",
actions: "sendGAEvent",
},
},
},
toggleAllowMeetings: {
invoke: {
id: "toggleAllowMeetings",
src: "toggleAllowMeetings",
onDone: { target: "home", actions: ["toggleAllowMeetings"] },
},
},
},
},
},
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment