diff --git a/common/src/commonMain/kotlin/CommonMessagesCommandsFilter.kt b/common/src/commonMain/kotlin/CommonMessagesCommandsFilter.kt index 2eac06e..988e8d8 100644 --- a/common/src/commonMain/kotlin/CommonMessagesCommandsFilter.kt +++ b/common/src/commonMain/kotlin/CommonMessagesCommandsFilter.kt @@ -2,13 +2,14 @@ package dev.inmo.plaguposter.common import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.CommonMessageFilterExcludeMediaGroups import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.SimpleFilter +import dev.inmo.tgbotapi.extensions.utils.contentMessageOrNull import dev.inmo.tgbotapi.extensions.utils.textContentOrNull +import dev.inmo.tgbotapi.extensions.utils.withContentOrNull import dev.inmo.tgbotapi.types.BotCommand import dev.inmo.tgbotapi.types.message.abstracts.* +import dev.inmo.tgbotapi.types.message.content.TextContent import dev.inmo.tgbotapi.types.message.textsources.BotCommandTextSource val FirstSourceIsCommandsFilter = SimpleFilter { - it is ContentMessage<*> && it.content.textContentOrNull() ?.textSources ?.firstOrNull { - it is BotCommandTextSource - } != null + it.contentMessageOrNull() ?.withContentOrNull() ?.content ?.textSources ?.firstOrNull() is BotCommandTextSource } diff --git a/posts_registrar/src/jvmMain/kotlin/Plugin.kt b/posts_registrar/src/jvmMain/kotlin/Plugin.kt index ecdf6d7..30e17fd 100644 --- a/posts_registrar/src/jvmMain/kotlin/Plugin.kt +++ b/posts_registrar/src/jvmMain/kotlin/Plugin.kt @@ -18,84 +18,95 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextWithFSM import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.* import dev.inmo.tgbotapi.extensions.behaviour_builder.strictlyOn import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.* -import dev.inmo.tgbotapi.extensions.utils.extensions.raw.text import dev.inmo.tgbotapi.extensions.utils.extensions.sameChat import dev.inmo.tgbotapi.extensions.utils.extensions.sameMessage import dev.inmo.tgbotapi.extensions.utils.textContentOrNull import dev.inmo.tgbotapi.extensions.utils.types.buttons.* -import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage -import dev.inmo.tgbotapi.types.message.content.MediaGroupContent -import dev.inmo.tgbotapi.types.message.content.MessageContent import dev.inmo.tgbotapi.utils.regular +import kotlinx.coroutines.async import kotlinx.coroutines.flow.* import kotlinx.serialization.Serializable import org.koin.core.Koin @Serializable object Plugin : Plugin { + @Serializable + data class Config( + val useInlineFinishingOpportunity: Boolean = true + ) + override suspend fun BehaviourContextWithFSM.setupBotPlugin(koin: Koin) { val config = koin.get() val postsRepo = koin.get() - strictlyOn {state: RegistrationState.InProcess -> + strictlyOn { state: RegistrationState.InProcess -> val buttonUuid = "finish" - val messageToDelete = send( - state.context, - dev.inmo.tgbotapi.utils.buildEntities { - if (state.messages.isNotEmpty()) { - regular("Your message(s) has been registered. You may send new ones or push \"Finish\" to finalize your post") + val suggestionMessageDeferred = async { + send( + state.context, + dev.inmo.tgbotapi.utils.buildEntities { + if (state.messages.isNotEmpty()) { + regular("Your message(s) has been registered. You may send new ones or push \"Finish\" to finalize your post") + } else { + regular("Ok, send me your messages for new post") + } + }, + replyMarkup = if (state.messages.isNotEmpty()) { + flatInlineKeyboard { + dataButton( + "Finish", + buttonUuid + ) + } } else { - regular("Ok, send me your messages for new post") + null } - }, - replyMarkup = if (state.messages.isNotEmpty()) { - flatInlineKeyboard { - dataButton( - "Finish", - buttonUuid - ) - } - } else { - null - } - ) + ) + } - val newMessagesInfo = firstOf { + firstOf { add { - listOf( - waitAnyContentMessage().filter { - it.chat.id == state.context && it.content.textContentOrNull() ?.text != "/finish_post" - }.take(1).first() - ) + val receivedMessage = waitAnyContentMessage().filter { + it.sameChat(state.context) + }.first() + + when { + receivedMessage.content.textContentOrNull() ?.text == "/finish_post" -> { + val messageToDelete = suggestionMessageDeferred.await() + edit(messageToDelete, "Ok, finishing your request") + RegistrationState.Finish( + state.context, + state.messages + ) + } + else -> { + RegistrationState.InProcess( + state.context, + state.messages + PostContentInfo.fromMessage(receivedMessage) + ).also { + runCatchingSafely { + suggestionMessageDeferred.cancel() + } + runCatchingSafely { + delete(suggestionMessageDeferred.await()) + } + } + } + } } add { + val messageToDelete = suggestionMessageDeferred.await() val finishPressed = waitMessageDataCallbackQuery().filter { it.message.sameMessage(messageToDelete) && it.data == buttonUuid }.first() - emptyList>() - } - add { - val finishPressed = waitTextMessage().filter { - it.sameChat(messageToDelete) && it.content.text == "/finish_post" - }.first() - emptyList>() - } - }.ifEmpty { - edit(messageToDelete, "Ok, finishing your request") - return@strictlyOn RegistrationState.Finish( - state.context, - state.messages - ) - }.flatMap { - PostContentInfo.fromMessage(it) - } - RegistrationState.InProcess( - state.context, - state.messages + newMessagesInfo - ).also { - delete(messageToDelete) + edit(messageToDelete, "Ok, finishing your request") + RegistrationState.Finish( + state.context, + state.messages + ) + } } } @@ -108,12 +119,12 @@ object Plugin : Plugin { null } - onCommand("start_post", initialFilter = { it.chat.id == config.sourceChatId }) { + onCommand("start_post", initialFilter = { it.sameChat(config.sourceChatId) }) { startChain(RegistrationState.InProcess(it.chat.id, emptyList())) } onContentMessage( - initialFilter = { it.chat.id == config.sourceChatId && !FirstSourceIsCommandsFilter(it) } + initialFilter = { it.sameChat(config.sourceChatId) && !FirstSourceIsCommandsFilter(it) } ) { startChain(RegistrationState.Finish(it.chat.id, PostContentInfo.fromMessage(it))) } diff --git a/runner/deploy.sh b/runner/deploy.sh index 0c68c50..5398972 100755 --- a/runner/deploy.sh +++ b/runner/deploy.sh @@ -15,7 +15,7 @@ function assert_success() { app=plaguposter version="`grep ../gradle.properties -e "^version=" | sed -e "s/version=\(.*\)/\1/"`" -server=docker.io/insanusmokrassar +server=insanusmokrassar assert_success ../gradlew build assert_success sudo docker build -t $app:"$version" .