82 lines
2.7 KiB
TypeScript
82 lines
2.7 KiB
TypeScript
import { ChoiceInputBlock, SessionState } from '@typebot.io/schemas'
|
|
import { injectVariableValuesInButtonsInputBlock } from './injectVariableValuesInButtonsInputBlock'
|
|
import { ParsedReply } from '../../../types'
|
|
|
|
export const parseButtonsReply =
|
|
(state: SessionState) =>
|
|
(inputValue: string, block: ChoiceInputBlock): ParsedReply => {
|
|
const displayedItems =
|
|
injectVariableValuesInButtonsInputBlock(state)(block).items
|
|
if (block.options?.isMultipleChoice) {
|
|
const longestItemsFirst = [...displayedItems].sort(
|
|
(a, b) => (b.content?.length ?? 0) - (a.content?.length ?? 0)
|
|
)
|
|
const matchedItemsByContent = longestItemsFirst.reduce<{
|
|
strippedInput: string
|
|
matchedItemIds: string[]
|
|
}>(
|
|
(acc, item) => {
|
|
if (
|
|
item.content &&
|
|
acc.strippedInput
|
|
.toLowerCase()
|
|
.includes(item.content.trim().toLowerCase())
|
|
)
|
|
return {
|
|
strippedInput: acc.strippedInput.replace(item.content ?? '', ''),
|
|
matchedItemIds: [...acc.matchedItemIds, item.id],
|
|
}
|
|
return acc
|
|
},
|
|
{
|
|
strippedInput: inputValue.trim(),
|
|
matchedItemIds: [],
|
|
}
|
|
)
|
|
const remainingItems = displayedItems.filter(
|
|
(item) => !matchedItemsByContent.matchedItemIds.includes(item.id)
|
|
)
|
|
const matchedItemsByIndex = remainingItems.reduce<{
|
|
strippedInput: string
|
|
matchedItemIds: string[]
|
|
}>(
|
|
(acc, item, idx) => {
|
|
if (acc.strippedInput.includes(`${idx + 1}`))
|
|
return {
|
|
strippedInput: acc.strippedInput.replace(`${idx + 1}`, ''),
|
|
matchedItemIds: [...acc.matchedItemIds, item.id],
|
|
}
|
|
return acc
|
|
},
|
|
{
|
|
strippedInput: matchedItemsByContent.strippedInput,
|
|
matchedItemIds: [],
|
|
}
|
|
)
|
|
const matchedItems = displayedItems.filter((item) =>
|
|
[
|
|
...matchedItemsByContent.matchedItemIds,
|
|
...matchedItemsByIndex.matchedItemIds,
|
|
].includes(item.id)
|
|
)
|
|
if (matchedItems.length === 0) return { status: 'fail' }
|
|
return {
|
|
status: 'success',
|
|
reply: matchedItems.map((item) => item.content).join(', '),
|
|
}
|
|
}
|
|
const longestItemsFirst = [...displayedItems].sort(
|
|
(a, b) => (b.content?.length ?? 0) - (a.content?.length ?? 0)
|
|
)
|
|
const matchedItem = longestItemsFirst.find(
|
|
(item) =>
|
|
item.id === inputValue ||
|
|
(item.content && inputValue.trim() === item.content.trim())
|
|
)
|
|
if (!matchedItem) return { status: 'fail' }
|
|
return {
|
|
status: 'success',
|
|
reply: matchedItem.content ?? '',
|
|
}
|
|
}
|