From 93b0116a971178ff6d84a045dd4fc05bd3806259 Mon Sep 17 00:00:00 2001 From: etrex kuo Date: Tue, 26 May 2020 13:42:26 +0800 Subject: [PATCH] feat: remove getAction --- examples/basic/index.js | 33 ++++--- examples/line-confirm-template/index.js | 90 +++++++++---------- examples/line-datetime-picker/index.js | 13 ++- examples/line-quick-replies/index.js | 5 +- examples/messenger-quick-replies/index.js | 5 +- examples/slot-filling-confirmation/index.js | 97 ++++++++++----------- index.js | 49 +++++++---- 7 files changed, 151 insertions(+), 141 deletions(-) diff --git a/examples/basic/index.js b/examples/basic/index.js index 13196c7..f476510 100644 --- a/examples/basic/index.js +++ b/examples/basic/index.js @@ -1,29 +1,28 @@ const { registerAction, - getAction, run, prompt, } = require('@bottender/proposal-conversation'); // Register the action before handling events -registerAction('AskLikeCheeseOrNot', async function AskLikeCheeseOrNot( - context, - props -) { - if (!props.result) { - await context.sendText('Do you like cheese? (yes/no)'); - return prompt('result'); - } +const AskLikeCheeseOrNot = registerAction( + 'AskLikeCheeseOrNot', + async function AskLikeCheeseOrNot(context, props) { + if (!props.result) { + await context.sendText('Do you like cheese? (yes/no)'); + return prompt('result'); + } - if (props.result === 'yes') { - await context.sendText('You said yes! How wonderful.'); - } else if (props.result === 'no') { - await context.sendText('You said no, that is too bad.'); - } else { - await context.sendText('Sorry I did not understand.'); + if (props.result === 'yes') { + await context.sendText('You said yes! How wonderful.'); + } else if (props.result === 'no') { + await context.sendText('You said no, that is too bad.'); + } else { + await context.sendText('Sorry I did not understand.'); + } } -}); +); module.exports = run(function App() { - return getAction('AskLikeCheeseOrNot'); + return AskLikeCheeseOrNot; }); diff --git a/examples/line-confirm-template/index.js b/examples/line-confirm-template/index.js index 79338ec..c46b1cb 100644 --- a/examples/line-confirm-template/index.js +++ b/examples/line-confirm-template/index.js @@ -1,12 +1,11 @@ const { router, text } = require('bottender/router'); const { registerAction, - getAction, run, prompt, } = require('@bottender/proposal-conversation'); -registerAction( +const AskLikeCheeseOrNotByTextActions = registerAction( 'AskLikeCheeseOrNotByTextActions', async function AskLikeCheeseOrNotByTextActions(context, props) { if (!props.result) { @@ -38,54 +37,57 @@ registerAction( } ); -registerAction('AskLikeCheeseOrNotByPayloadActions', { - getProps: ({ key, context, prevProps }) => { - if (key === 'result' && context.event.isPayload) { +const AskLikeCheeseOrNotByPayloadActions = registerAction( + 'AskLikeCheeseOrNotByPayloadActions', + { + getProps: ({ key, context, prevProps }) => { + if (key === 'result' && context.event.isPayload) { + return { + ...prevProps, + result: context.event.payload === 'YES' ? 'yes' : 'no', + }; + } return { ...prevProps, - result: context.event.payload === 'YES' ? 'yes' : 'no', + [key]: context.event.text, }; - } - return { - ...prevProps, - [key]: context.event.text, - }; - }, - action: async function AskLikeCheeseOrNotByPayloadActions(context, props) { - if (!props.result) { - await context.sendConfirmTemplate('Do you like cheese?', { - text: 'Do you like cheese?', - actions: [ - { - type: 'postback', - label: 'Yes', - data: 'YES', - displayText: 'yes', - }, - { - type: 'postback', - label: 'No', - data: 'NO', - displayText: 'no', - }, - ], - }); - return prompt('result'); - } + }, + action: async function AskLikeCheeseOrNotByPayloadActions(context, props) { + if (!props.result) { + await context.sendConfirmTemplate('Do you like cheese?', { + text: 'Do you like cheese?', + actions: [ + { + type: 'postback', + label: 'Yes', + data: 'YES', + displayText: 'yes', + }, + { + type: 'postback', + label: 'No', + data: 'NO', + displayText: 'no', + }, + ], + }); + return prompt('result'); + } - if (props.result === 'yes') { - await context.sendText('You said yes! How wonderful.'); - } else if (props.result === 'no') { - await context.sendText('You said no, that is too bad.'); - } else { - await context.sendText('Sorry I did not understand.'); - } - }, -}); + if (props.result === 'yes') { + await context.sendText('You said yes! How wonderful.'); + } else if (props.result === 'no') { + await context.sendText('You said no, that is too bad.'); + } else { + await context.sendText('Sorry I did not understand.'); + } + }, + } +); module.exports = run(function App() { return router([ - text('payload', getAction('AskLikeCheeseOrNotByPayloadActions')), - text('*', getAction('AskLikeCheeseOrNotByTextActions')), + text('payload', AskLikeCheeseOrNotByPayloadActions), + text('*', AskLikeCheeseOrNotByTextActions), ]); }); diff --git a/examples/line-datetime-picker/index.js b/examples/line-datetime-picker/index.js index 6706e1c..f3d97c3 100644 --- a/examples/line-datetime-picker/index.js +++ b/examples/line-datetime-picker/index.js @@ -1,12 +1,11 @@ const { router, text } = require('bottender/router'); const { registerAction, - getAction, run, prompt, } = require('@bottender/proposal-conversation'); -registerAction('AskDate', { +const AskDate = registerAction('AskDate', { getProps: ({ key, context, prevProps }) => { if ( key === 'date' && @@ -47,7 +46,7 @@ registerAction('AskDate', { }, }); -registerAction('AskTime', { +const AskTime = registerAction('AskTime', { getProps: ({ key, context, prevProps }) => { if ( key === 'time' && @@ -88,7 +87,7 @@ registerAction('AskTime', { }, }); -registerAction('AskDatetime', { +const AskDatetime = registerAction('AskDatetime', { getProps: ({ key, context, prevProps }) => { if ( key === 'datetime' && @@ -131,8 +130,8 @@ registerAction('AskDatetime', { module.exports = run(function App() { return router([ - text('date', getAction('AskDate')), - text('time', getAction('AskTime')), - text('*', getAction('AskDatetime')), + text('date', AskDate), + text('time', AskTime), + text('*', AskDatetime), ]); }); diff --git a/examples/line-quick-replies/index.js b/examples/line-quick-replies/index.js index 9ad1cac..b0952a7 100644 --- a/examples/line-quick-replies/index.js +++ b/examples/line-quick-replies/index.js @@ -1,11 +1,10 @@ const { registerAction, - getAction, run, prompt, } = require('@bottender/proposal-conversation'); -registerAction( +const AskLikeCheeseOrNotByTextQuickReplies = registerAction( 'AskLikeCheeseOrNotByTextQuickReplies', async function AskLikeCheeseOrNotByTextQuickReplies(context, props) { if (!props.result) { @@ -45,5 +44,5 @@ registerAction( ); module.exports = run(function App() { - return getAction('AskLikeCheeseOrNotByTextQuickReplies'); + return AskLikeCheeseOrNotByTextQuickReplies; }); diff --git a/examples/messenger-quick-replies/index.js b/examples/messenger-quick-replies/index.js index 2755d06..5da57b3 100644 --- a/examples/messenger-quick-replies/index.js +++ b/examples/messenger-quick-replies/index.js @@ -1,11 +1,10 @@ const { registerAction, - getAction, run, prompt, } = require('@bottender/proposal-conversation'); -registerAction( +const AskLikeCheeseOrNotByTextQuickReplies = registerAction( 'AskLikeCheeseOrNotByTextQuickReplies', async function AskLikeCheeseOrNotByTextQuickReplies(context, props) { if (!props.result) { @@ -37,5 +36,5 @@ registerAction( ); module.exports = run(function App() { - return getAction('AskLikeCheeseOrNotByTextQuickReplies'); + return AskLikeCheeseOrNotByTextQuickReplies; }); diff --git a/examples/slot-filling-confirmation/index.js b/examples/slot-filling-confirmation/index.js index 990b520..36bb156 100644 --- a/examples/slot-filling-confirmation/index.js +++ b/examples/slot-filling-confirmation/index.js @@ -1,66 +1,65 @@ const { registerAction, - getAction, run, prompt, setField, deleteField, } = require('@bottender/proposal-conversation'); -registerAction('AskNameAndPhone', async function AskNameAndPhone( - context, - props -) { - if (!props.name) { - await context.sendText('Please type your name:'); - return prompt('name'); - } +const AskNameAndPhone = registerAction( + 'AskNameAndPhone', + async function AskNameAndPhone(context, props) { + if (!props.name) { + await context.sendText('Please type your name:'); + return prompt('name'); + } - if (props.name.length > 30) { - const name = `${props.name.slice(0, 27)}...`; - setField(context, 'name', name); - await context.sendText( - `Name can't be more than 30 characters. Set your name to ${name}` - ); - } + if (props.name.length > 30) { + const name = `${props.name.slice(0, 27)}...`; + setField(context, 'name', name); + await context.sendText( + `Name can't be more than 30 characters. Set your name to ${name}` + ); + } - if (!props.phone) { - await context.sendText('Please type your phone number (10 digits):'); - return prompt('phone'); - } + if (!props.phone) { + await context.sendText('Please type your phone number (10 digits):'); + return prompt('phone'); + } - if (props.phone && props.phone.length !== 10) { - await context.sendText( - `Your input ${props.phone} is invalid. Please retype your phone again (10 digits):` - ); - return prompt('phone'); - } + if (props.phone && props.phone.length !== 10) { + await context.sendText( + `Your input ${props.phone} is invalid. Please retype your phone again (10 digits):` + ); + return prompt('phone'); + } - if (!props.confirm) { - await context.sendText( - `${props.name}, your phone number is ${props.phone}, right? If not, which part you want to refill? (yes|name|phone|both)` - ); - return prompt('confirm'); - } + if (!props.confirm) { + await context.sendText( + `${props.name}, your phone number is ${props.phone}, right? If not, which part you want to refill? (yes|name|phone|both)` + ); + return prompt('confirm'); + } - if (props.confirm === 'yes') { - await context.sendText( - `Thank you for your help, your personal data was stored correctly.` - ); - } else if (props.confirm === 'name') { - deleteField(context, ['name', 'confirm']); - await context.sendText('Please retype your name:'); - return prompt('name'); - } else if (props.confirm === 'phone') { - deleteField(context, ['phone', 'confirm']); - await context.sendText('Please retype your phone again (10 digits):'); - return prompt('phone'); - } else if (props.confirm === 'both') { - deleteField(context, ['confirm', 'name', 'phone']); - return getAction('AskNameAndPhone'); + if (props.confirm === 'yes') { + await context.sendText( + `Thank you for your help, your personal data was stored correctly.` + ); + } else if (props.confirm === 'name') { + deleteField(context, ['name', 'confirm']); + await context.sendText('Please retype your name:'); + return prompt('name'); + } else if (props.confirm === 'phone') { + deleteField(context, ['phone', 'confirm']); + await context.sendText('Please retype your phone again (10 digits):'); + return prompt('phone'); + } else if (props.confirm === 'both') { + deleteField(context, ['confirm', 'name', 'phone']); + return AskNameAndPhone; + } } -}); +); module.exports = run(function App() { - return getAction('AskNameAndPhone'); + return AskNameAndPhone; }); diff --git a/index.js b/index.js index 26f0294..20e1e01 100644 --- a/index.js +++ b/index.js @@ -15,32 +15,45 @@ function defaultGetProps({ key, context, prevProps }) { }; } -/** - * register the action - */ -function registerAction(name, action) { - if (typeof action === 'function') { - actions[name] = { - action, - getProps: defaultGetProps, - }; - } else { - actions[name] = action; - } -} - function getAction(name) { invariant( actions[name] && typeof actions[name].action === 'function', `The ${name} action is not registered.` ); - return function SetCurrentAction(context, props) { + return actions[name].action; +} + +/** + * register the action + */ +function registerAction(name, options) { + let action; + if (typeof options === 'function') { + action = options; + } else { + action = options.action; + } + + function SetCurrentAction(context, props) { // FIXME: avoid using state to label current action context.setState({ currentAction: name }); + return action(context, props); + } - return actions[name].action(context, props); - }; + if (typeof options === 'function') { + actions[name] = { + action: SetCurrentAction, + getProps: defaultGetProps, + }; + } else { + actions[name] = { + ...options, + action: SetCurrentAction, + }; + } + + return getAction(name); } /** @@ -127,7 +140,7 @@ function run(action) { next = await next(context, {}); } - if (next && next.isPrompt) { + if (next && next.isPrompt && context.state.currentAction) { const returnPrompt = next; const newLock = {