Skip to content

Instantly share code, notes, and snippets.

@marcmartino
Last active June 1, 2020 01:15
Show Gist options
  • Save marcmartino/57f2fef01fe3558c75d3adec9126a395 to your computer and use it in GitHub Desktop.
Save marcmartino/57f2fef01fe3558c75d3adec9126a395 to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
const setSpeechNodeContext = (lang, text) =>
assign({
speechNodeTranscript: {
text,
lang,
},
});
const setListenNodeContext = (lang, responses) =>
assign({
listeningNodeTranscript: {
responses,
lang,
},
});
const isMatchingCapture = (x) => (context) => {
const captured = context.transcriptContext?.captured || "";
switch (typeof x) {
case "string":
return captured.indexOf(x) > -1;
case "object":
if (x instanceof RegExp) return !!captured.match(x);
default:
return true;
}
};
const speechMachine = Machine(
{
id: "Flashcard",
initial: "selectedWordList",
strict: true,
context: {
speechNodeTranscript: {},
listeningNodeTranscript: {},
transcriptContext: {},
},
states: {
selectedWordList: {
on: {
FETCH: { target: "card.loadingQueuedWords" },
},
},
// error: {
// id: "error",
// type: "final",
// },
card: {
id: "card",
states: {
loadingQueuedWords: {
entry: assign({incorrectAttempts: 0}),
on: {
RESOLVE: { target: "presentFlashcardSpeech" },
// ERROR: { target: '#error' }
},
},
presentFlashcardSpeech: {
entry: setSpeechNodeContext("es-AR", "la palabra"),
exit: "clearTranscriptNodes",
on: {
SUCCESS: { target: "flashcardResponseListen" },
},
},
flashcardResponseListen: {
entry: setListenNodeContext("en-US", [
{ test: /help/gi, action: "SUPPLY_ANSWER" },
{ test: /help/gi, action: "CARD_RESOURCES_STATEMENT" },
{ test: /help/gi, action: "HELP_STATEMENT" },
{ test: /help/gi, action: "APP_NAVIGATION_STATEMENT" },
]),
exit: "clearTranscriptNodes",
on: {
SUPPLY_ANSWER: { target: "evaluateAnswer" },
CARD_RESOURCES_STATEMENT: {
target: "#cardResources",
},
HELP_STATEMENT: { target: "#help.entry" },
APP_NAVIGATION_STATEMENT: {
target: "#appNav",
actions: assign({ transcriptContext: { captured: "pause" } }),
},
},
},
evaluateAnswer: {
on: {
CORRECT: { target: "correctAnswer" },
INCORRECT: { target: "incorrectAnswer" },
},
},
correctAnswer: {
on: {
"": { target: "optionalReviewIdle" },
},
},
optionalReviewIdle: {
on: {
"": {
target: "loadingQueuedWords",
cond: (context) => context.skipWordReview,
},
NEXT: { target: "loadingQueuedWords" },
},
},
incorrectAnswer: {
on: {
"": {
actions: assign((context) => ({incorrectAttempts: context.incorrectAttempts + 1})),
target: "presentFlashcardSpeech",
},
},
},
},
},
cardResourceMenu: {
id: "cardResources",
initial: "describeCardRoot",
states: {
describeCardRoot: {
on: {
"": { target: "describeCardSpeech" },
},
},
describeCardSpeech: {
entry: setSpeechNodeContext(
"en-US",
"This sentence will recap the card, probably by reiterating the cloze or similar"
),
exit: "clearTranscriptNodes",
on: {
SUCCESS: { target: "describeCardListen" },
// ERROR: { target: '#error' }
},
},
describeCardListen: {
entry: setListenNodeContext("en-US", [
{ test: /prev/gi, action: "REQUEST_PREVIOUS_CARD_DESCRIPTION" },
{
test: /forward/gi,
action: "REQUEST_PROXIMAL_CARD_DESCRIPTION",
},
{ test: /current/gi, action: "REQUEST_CURRENT_CARD_DESCRIPTION" },
{ test: /definition/gi, action: "REQUEST_DEFINITION" },
{ test: /sentence/gi, action: "REQUEST_EXAMPLE_SENTENCES" },
{ test: /conjugation/gi, action: "REQUEST_CONJUGATIONS" },
{ test: /return/gi, action: "RETURN" },
]),
exit: "clearTranscriptNodes",
on: {
REQUEST_PREVIOUS_CARD_DESCRIPTION: {
target: "describeCardSpeech",
},
REQUEST_PROXIMAL_CARD_DESCRIPTION: {
target: "describeCardSpeech",
},
REQUEST_CURRENT_CARD_DESCRIPTION: {
target: "describeCardSpeech",
},
REQUEST_DEFINITION: { target: "cardDefinitionsSpeech" },
REQUEST_EXAMPLE_SENTENCES: { target: "cardSentencesSpeech" },
REQUEST_CONJUGATIONS: { target: "cardConjugationsSpeech" },
RETURN: { target: "#card.presentFlashcardSpeech" },
// ERROR: { target: '#error' }
},
},
cardDefinitionsSpeech: {
entry: setSpeechNodeContext(
"en-US",
"This give the definition of the word"
),
exit: "clearTranscriptNodes",
on: {
SUCCESS: { target: "describeCardListen" },
// ERROR: { target: '#elsewhere' }
},
},
cardSentencesSpeech: {
entry: setSpeechNodeContext(
"en-US",
"This will give the example sentences of the phrase"
),
exit: "clearTranscriptNodes",
on: {
SUCCESS: { target: "describeCardListen" },
// ERROR: { target: '#elsewhere' }
},
},
cardConjugationsSpeech: {
entry: setSpeechNodeContext(
"en-US",
"This will give the conjugations of the phrase"
),
exit: "clearTranscriptNodes",
on: {
SUCCESS: { target: "describeCardListen" },
// ERROR: { target: '#elsewhere' }
},
},
},
},
helpMenu: {
id: "help",
states: {
entry: {
type: "final",
},
},
},
appNavigationMenu: {
id: "appNav",
states: {
root: {
on: {
"": [
{
target: "nextSpeech",
cond: isMatchingCapture("next"),
},
{ target: "pausedSpeech", cond: isMatchingCapture("pause") },
{ target: "exitSpeech", cond: isMatchingCapture("exit") },
],
},
},
nextSpeech: {
entry: assign({
speechNodeTranscript: {
lang: "en-US",
text: "OK, next!",
},
}),
exit: "clearTranscriptNodes",
on: {
SUCCESS: { target: "#card.loadingQueuedWords" },
//ERROR: {target: "#error",},
},
},
pausedSpeech: {
entry: assign({
speechNodeTranscript: {
lang: "en-US",
text:
"Session paused, please press the button on screen to resume",
},
}),
exit: "clearTranscriptNodes",
on: {
SUCCESS: { target: "pauseIdle" },
//ERROR: {target: "#error",},
},
},
pauseIdle: {
on: {
UNPAUSE: { target: "#card.presentFlashcardSpeech" },
},
},
exitSpeech: {
entry: assign({
speechNodeTranscript: {
lang: "en-US",
text: "Goodbye",
},
}),
exit: "clearTranscriptNodes",
on: {
SUCCESS: { target: "exiting" },
//ERROR: {target: "#error",},
},
},
exiting: {
type: "final",
},
},
},
},
},
{
actions: {
clearTranscriptNodes: assign({
speechNodeTranscript: {},
listeningNodeTranscript: {},
}),
},
}
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment