Skip to content

Commit

Permalink
feat: setParentMenuAfter allows to set the parent menu after doFunc
Browse files Browse the repository at this point in the history
  • Loading branch information
EdJoPaTo committed Sep 21, 2018
1 parent 39b335b commit f2874ba
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 5 deletions.
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ settings.setCommand('settings')
main.submenu('Settings', 's', settings)
```

### `menu.button(text, action, {doFunc, hide, joinLastRow})`
### `menu.button(text, action, {doFunc, hide, joinLastRow, setParentMenuAfter})`

Button for triggering functions.
Updates menu when `doFunc()` finished.
Expand All @@ -106,8 +106,11 @@ It has the exact same arguments and will not update the menu after the `doFunc()
`action` has to be unique in this menu.

`doFunc(ctx)` will be triggered when user presses the button.

`hide(ctx)` (optional) can hide the button when return is true.

`setParentMenuAfter` (optional) can be set to true in order to open the parent menu instead of the current menu after the doFunc was executed.

### `menu.simpleButton(text, action, {doFunc, hide, joinLastRow})`

see `menu.button`
Expand All @@ -133,7 +136,7 @@ If this is not unique it will collide with the other question with the same text

`hide(ctx)` (optional) can hide the button when return is true.

### `menu.select(action, options, {setFunc, submenu, isSetFunc, prefixFunc, hide, joinLastRow, columns, maxRows})`
### `menu.select(action, options, {setFunc, submenu, isSetFunc, prefixFunc, hide, joinLastRow, columns, maxRows, setParentMenuAfter})`

Creates multiple buttons for each provided option.

Expand Down Expand Up @@ -172,6 +175,9 @@ Can not be used when `submenu` is set.

`maxRows` (Integer, optional) can be provided to limit the maximal rows of buttons. (default: 10)

`setParentMenuAfter` (optional) can be set to true in order to open the parent menu instead of the current menu after the setFunc was executed.
Only has an effect when `setFunc` is used.

### `menu.toggle(text, action, {setFunc, isSetFunc, hide, joinLastRow})`

Creates a button that toggles a setting.
Expand Down
18 changes: 15 additions & 3 deletions inline-menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ class TelegrafInlineMenu {
if (ctx.callbackQuery) {
const expectedPartCount = options.depth
const actualParts = ctx.callbackQuery.data.split(':')
if (actualParts.length === 1 + expectedPartCount) {
// Go up to the menu that shall be opened
while (actualParts.length > expectedPartCount) {
actualParts.pop()
}
const menuAction = actualParts.join(':')
Expand Down Expand Up @@ -137,6 +138,7 @@ class TelegrafInlineMenu {

const subOptions = {
...options,
setParentMenuFunc: setMenuFunc,
depth: options.depth + 1
}

Expand Down Expand Up @@ -165,8 +167,16 @@ class TelegrafInlineMenu {
} else {
middleware = handler.middleware
}
if (handler.setMenuAfter) {
middlewareOptions.afterFunc = ctx => setMenuFunc(ctx, 'after handler ' + (childActionCode || actionCode).get())
if (handler.setParentMenuAfter || handler.setMenuAfter) {
const reason = 'after handler ' + (childActionCode || actionCode).get()
if (handler.setParentMenuAfter) {
if (!options.setParentMenuFunc) {
throw new Error('Action will not be able to set parent menu as there is no parent menu: ' + actionCode.get())
}
middlewareOptions.afterFunc = ctx => options.setParentMenuFunc(ctx, reason)
} else {
middlewareOptions.afterFunc = ctx => setMenuFunc(ctx, reason)
}
}
return createHandlerMiddleware(middleware, middlewareOptions)
})
Expand Down Expand Up @@ -226,6 +236,7 @@ class TelegrafInlineMenu {
action: new ActionCode(action),
hide: additionalArgs.hide,
middleware: additionalArgs.doFunc,
setParentMenuAfter: additionalArgs.setParentMenuAfter,
setMenuAfter: additionalArgs.setMenuAfter
})
return this.manual(text, action, additionalArgs)
Expand Down Expand Up @@ -301,6 +312,7 @@ class TelegrafInlineMenu {
if (setFunc) {
const hitSelectButton = ctx => setFunc(ctx, keyFromCtx(ctx))
handler.middleware = hitSelectButton
handler.setParentMenuAfter = additionalArgs.setParentMenuAfter
handler.setMenuAfter = true
} else if (submenu) {
handler.submenu = submenu
Expand Down
43 changes: 43 additions & 0 deletions test/submenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,46 @@ test('default init is main', async t => {
bot.context.editMessageText = () => Promise.resolve(t.pass())
await bot.handleUpdate({callback_query: {data: 'main'}})
})

test('setParentMenuAfter', async t => {
t.plan(5)
const menu = new TelegrafInlineMenu('foo')
menu.submenu('submenu', 's', new TelegrafInlineMenu('bar'))
.simpleButton('button', 'b', {
setParentMenuAfter: true,
doFunc: t.pass
})

const bot = new Telegraf()
bot.use(menu.init({actionCode: 'a'}))
bot.context.editMessageText = (text, extra) => {
t.is(text, 'foo')
t.deepEqual(extra.reply_markup.inline_keyboard, [[{
text: 'submenu',
callback_data: 'a:s'
}]])
return Promise.resolve()
}
bot.use(ctx => {
t.log(ctx.update)
t.fail('update missed')
})

// +2
await bot.handleUpdate({callback_query: {data: 'a'}})
// +2
await bot.handleUpdate({callback_query: {data: 'a:s:b'}})
})

test('setParentMenuAfter when there is no parent fails', t => {
const menu = new TelegrafInlineMenu('foo')
.simpleButton('button', 'b', {
setParentMenuAfter: true,
doFunc: t.fail
})

const bot = new Telegraf()
t.throws(() => {
bot.use(menu.init())
}, /set parent menu.+main/)
})

0 comments on commit f2874ba

Please sign in to comment.