diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/buttons/InlineKeyboardMarkup.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/buttons/InlineKeyboardMarkup.kt index cd17bb80df..6b1e535101 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/buttons/InlineKeyboardMarkup.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/buttons/InlineKeyboardMarkup.kt @@ -25,4 +25,23 @@ data class InlineKeyboardMarkup( } } } + + operator fun plus(other: InlineKeyboardMarkup): InlineKeyboardMarkup { + return InlineKeyboardMarkup( + keyboard + other.keyboard + ) + } + + operator fun minus(other: InlineKeyboardMarkup): InlineKeyboardMarkup { + val otherButtons = other.keyboard.flatten() + return InlineKeyboardMarkup( + keyboard.mapNotNull { row -> + row.filter { button -> + button !in otherButtons + }.takeIf { + it.isNotEmpty() + } + } + ) + } } diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/buttons/ReplyKeyboardMarkup.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/buttons/ReplyKeyboardMarkup.kt index 8ffecc9d3f..658792e00f 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/buttons/ReplyKeyboardMarkup.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/buttons/ReplyKeyboardMarkup.kt @@ -22,4 +22,32 @@ data class ReplyKeyboardMarkup( error("Field $inputFieldPlaceholderField length must be in $inputFieldPlaceholderLimit, but was ${inputFieldPlaceholder.length}") } } + + fun add(other: ReplyKeyboardMarkup, placeholderDelimiter: String = "\n"): ReplyKeyboardMarkup { + return ReplyKeyboardMarkup( + keyboard = keyboard + other.keyboard, + resizeKeyboard = resizeKeyboard ?.or(other.resizeKeyboard ?: false) ?: other.resizeKeyboard, + oneTimeKeyboard = oneTimeKeyboard ?.or(other.oneTimeKeyboard ?: false) ?: other.oneTimeKeyboard, + inputFieldPlaceholder = inputFieldPlaceholder ?.plus(other.inputFieldPlaceholder ?.let { placeholderDelimiter + it } ?: "") ?: other.inputFieldPlaceholder, + selective = selective ?.or(other.selective ?: false) ?: other.selective, + persistent = persistent ?.or(other.persistent ?: false) ?: other.persistent, + ) + } + + operator fun plus(other: ReplyKeyboardMarkup): ReplyKeyboardMarkup { + return add(other) + } + + operator fun minus(other: ReplyKeyboardMarkup): ReplyKeyboardMarkup { + val otherButtons = other.keyboard.flatten() + return copy( + keyboard.mapNotNull { row -> + row.filter { button -> + button !in otherButtons + }.takeIf { + it.isNotEmpty() + } + } + ) + } } diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/Matrix.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/Matrix.kt index c14ae77d0e..935dc87eb3 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/Matrix.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/Matrix.kt @@ -1,5 +1,6 @@ package dev.inmo.tgbotapi.utils +import dev.inmo.micro_utils.common.withReplaced import dev.inmo.tgbotapi.types.buttons.Matrix /** @@ -67,6 +68,18 @@ open class RowBuilder { fun add(t: T) = mutRow.add(t) operator fun T.unaryPlus() = add(this) + + fun replace(i: Int, new: T) { + mutRow[i] = new + } + fun replace(old: T, new: T): Boolean { + val i = mutRow.indexOf(old).takeIf { it > -1 } ?: return false + replace(i, new) + return mutRow[i] == new + } + fun remove(i: Int): T { + return mutRow.removeAt(i) + } } open class MatrixBuilder { @@ -77,4 +90,18 @@ open class MatrixBuilder { fun add(t: List) = mutMatrix.add(t) operator fun plus(t: List) = add(t) operator fun T.unaryPlus() = add(listOf(this)) + + fun modifyRow(i: Int, block: RowBuilder.() -> Unit) { + val exists = matrix[i] + val rowBuilder = RowBuilder() + exists.forEach { rowBuilder.add(it) } + mutMatrix[i] = rowBuilder.apply(block).row + } + fun modifyRow(row: List, block: RowBuilder.() -> Unit) { + val i = mutMatrix.indexOf(row).takeIf { it > -1 } ?: return false + modifyRow(i, block) + } + fun remove(i: Int): List { + return mutMatrix.removeAt(i) + } } diff --git a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/types/buttons/InlineKeyboardBuilder.kt b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/types/buttons/InlineKeyboardBuilder.kt index f3a90dee90..152078de6f 100644 --- a/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/types/buttons/InlineKeyboardBuilder.kt +++ b/tgbotapi.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/types/buttons/InlineKeyboardBuilder.kt @@ -49,6 +49,19 @@ inline fun flatInlineKeyboard( block: InlineKeyboardRowBuilder.() -> Unit ) = inlineKeyboard { row(block) } +/** + * Factory-function for [InlineKeyboardBuilder]. It will [apply] [block] to internally created [InlineKeyboardMarkup] + * and [InlineKeyboardBuilder.build] [InlineKeyboardMarkup] then + * + * @see InlineKeyboardBuilder.row + */ +inline fun InlineKeyboardMarkup.modified( + block: InlineKeyboardBuilder.() -> Unit +) = InlineKeyboardBuilder().apply { + keyboard.forEach { add(it) } + block() +}.build() + /** * Creates and put [PayInlineKeyboardButton]