diff --git a/runner/build.gradle b/runner/build.gradle index d7cf67f..a0622f2 100644 --- a/runner/build.gradle +++ b/runner/build.gradle @@ -15,6 +15,7 @@ dependencies { api project(":plaguposter.posts_registrar") api project(":plaguposter.triggers.command") api project(":plaguposter.triggers.selector_with_timer") + api project(":plaguposter.triggers.timer") api project(":plaguposter.ratings") api project(":plaguposter.ratings.source") api project(":plaguposter.ratings.selector") diff --git a/triggers/timer/src/commonMain/kotlin/ButtonsBuilder.kt b/triggers/timer/src/commonMain/kotlin/ButtonsBuilder.kt index 2b18123..d78d569 100644 --- a/triggers/timer/src/commonMain/kotlin/ButtonsBuilder.kt +++ b/triggers/timer/src/commonMain/kotlin/ButtonsBuilder.kt @@ -6,42 +6,34 @@ import com.soywiz.klock.Month import com.soywiz.klock.Year import dev.inmo.plaguposter.common.SuccessfulSymbol import dev.inmo.plaguposter.posts.models.PostId -import dev.inmo.tgbotapi.extensions.api.answers.answer import dev.inmo.tgbotapi.extensions.api.edit.edit import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onMessageDataCallbackQuery -import dev.inmo.tgbotapi.extensions.utils.commonMessageOrNull -import dev.inmo.tgbotapi.extensions.utils.extensions.raw.reply_markup -import dev.inmo.tgbotapi.extensions.utils.ifCallbackDataInlineKeyboardButton -import dev.inmo.tgbotapi.extensions.utils.ifCommonMessage import dev.inmo.tgbotapi.extensions.utils.types.buttons.dataButton import dev.inmo.tgbotapi.extensions.utils.types.buttons.flatInlineKeyboard import dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard -import dev.inmo.tgbotapi.extensions.utils.withContent import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup -import dev.inmo.tgbotapi.types.queries.callback.MessageDataCallbackQuery import dev.inmo.tgbotapi.utils.row object ButtonsBuilder { - private const val changeHoursDataPrefix = "timer_hours" - private const val changeMinutesDataPrefix = "timer_minutes" - private const val changeDayDataPrefix = "timer_day" - private const val changeMonthDataPrefix = "timer_month" - private const val changeYearDataPrefix = "timer_year" - private const val changeDateDataPrefix = "timer_set" + private const val changeHoursDataPrefix = "timer_h" + private const val changeMinutesDataPrefix = "timer_m" + private const val changeDayDataPrefix = "timer_d" + private const val changeMonthDataPrefix = "timer_M" + private const val changeYearDataPrefix = "timer_y" + private const val changeDateDataPrefix = "timer_s" - private fun buildTimerButtons( + fun buildTimerButtons( postId: PostId, - dateTime: DateTime + dateTime: DateTimeTz ) = flatInlineKeyboard { - val unixMillis = dateTime.unixMillisLong - val local = dateTime.local - dataButton(local.hours.toString(), "$changeHoursDataPrefix $postId $unixMillis") - dataButton(":${local.minutes}", "$changeMinutesDataPrefix $postId $unixMillis") + val unixMillis = dateTime.utc.unixMillisLong + dataButton(dateTime.hours.toString(), "$changeHoursDataPrefix $postId $unixMillis") + dataButton(":${dateTime.minutes}", "$changeMinutesDataPrefix $postId $unixMillis") - dataButton(local.dayOfMonth.toString(), "$changeDayDataPrefix $postId $unixMillis") - dataButton(".${local.month1}", "$changeMonthDataPrefix $postId $unixMillis") - dataButton(".${local.yearInt}", "$changeYearDataPrefix $postId $unixMillis") + dataButton(dateTime.dayOfMonth.toString(), "$changeDayDataPrefix $postId $unixMillis") + dataButton(".${dateTime.month1}", "$changeMonthDataPrefix $postId $unixMillis") + dataButton(".${dateTime.yearInt}", "$changeYearDataPrefix $postId $unixMillis") dataButton(SuccessfulSymbol, "$changeDateDataPrefix $postId $unixMillis") } @@ -51,13 +43,14 @@ object ButtonsBuilder { prefix: String, postId: PostId, values: Iterable, - dateConverter: (Int) -> DateTime + min: DateTime = DateTime.now(), + dateConverter: (Int) -> DateTimeTz ): InlineKeyboardMarkup { return inlineKeyboard { values.chunked(5).forEach { row { it.forEach { - dataButton(it.toString(), "$prefix $postId ${dateConverter(it).unixMillisLong}") + dataButton(it.toString(), "$prefix $postId ${dateConverter(it).utc.unixMillisLong.coerceAtLeast(min.unixMillisLong)}") } } } @@ -66,21 +59,21 @@ object ButtonsBuilder { suspend fun buildStandardDataCallbackQuery( prefix: String, - possibleValues: (DateTime) -> Iterable, - dateTimeConverter: (Int, DateTime) -> DateTime + possibleValues: (DateTimeTz) -> Iterable, + dateTimeConverter: (Int, DateTimeTz) -> DateTimeTz ) { - val setPrefix = "${prefix}_set" + val setPrefix = "${prefix}s" onMessageDataCallbackQuery(Regex("$prefix .+")) { val (_, rawPostId, rawDateTimeMillis) = it.data.split(" ") val currentMillis = rawDateTimeMillis.toLongOrNull() ?: return@onMessageDataCallbackQuery - val currentDateTime = DateTime(currentMillis) + val currentDateTime = DateTime(currentMillis).local edit ( it.message, replyMarkup = buildKeyboard( setPrefix, PostId(rawPostId), - possibleValues(DateTime(currentMillis)) + possibleValues(currentDateTime) ) { dateTimeConverter(it, currentDateTime) } @@ -96,7 +89,7 @@ object ButtonsBuilder { it.message, buildTimerButtons( PostId(rawPostId), - currentDateTime + currentDateTime.local ) ) } @@ -108,64 +101,72 @@ object ButtonsBuilder { changeHoursDataPrefix, { val now = DateTime.now().local - val local = it.local - if (now.dateEq(local)) { + if (now.dateEq(it)) { now.hours .. 23 } else { 0 .. 23 } } ) { newValue, oldDateTime -> - oldDateTime.copyDayOfMonth(hours = newValue) // TODO::Fix issue in case of local and utc diff + DateTimeTz.local( + oldDateTime.local.copyDayOfMonth(hours = newValue), + oldDateTime.offset + ) } buildStandardDataCallbackQuery( changeMinutesDataPrefix, { val now = DateTime.now().local - val local = it.local - if (now.dateEq(local)) { - now.minutes .. 60 + if (now.dateEq(it) && now.hours >= it.hours) { + now.minutes until 60 } else { - 0 .. 60 + 0 until 60 } } ) { newValue, oldDateTime -> - oldDateTime.copyDayOfMonth(minutes = newValue) // TODO::Fix issue in case of local and utc diff + DateTimeTz.local( + oldDateTime.local.copyDayOfMonth(minutes = newValue), + oldDateTime.offset + ) } buildStandardDataCallbackQuery( changeDayDataPrefix, { val now = DateTime.now().local - val local = it.local - if (now.dateEq(local)) { + if (now.yearInt == it.yearInt && now.month0 == it.month0) { now.dayOfMonth .. it.month.days(it.year) } else { 1 .. it.month.days(it.year) } } ) { newValue, oldDateTime -> - oldDateTime.copyDayOfMonth(dayOfMonth = newValue) // TODO::Fix issue in case of local and utc diff + DateTimeTz.local( + oldDateTime.local.copyDayOfMonth(dayOfMonth = newValue), + oldDateTime.offset + ) } buildStandardDataCallbackQuery( changeMonthDataPrefix, { val now = DateTime.now().local - val local = it.local - if (now.year == local.year) { + if (now.year == it.year) { now.month1 .. 12 } else { 1 .. 12 } } ) { newValue, oldDateTime -> - oldDateTime.copyDayOfMonth(month = Month(newValue)) // TODO::Fix issue in case of local and utc diff + DateTimeTz.local( + oldDateTime.local.copyDayOfMonth(month = Month(newValue)), + oldDateTime.offset + ) } buildStandardDataCallbackQuery( @@ -174,7 +175,10 @@ object ButtonsBuilder { (it.year.year .. (it.year.year + 5)) } ) { newValue, oldDateTime -> - oldDateTime.copyDayOfMonth(year = Year(newValue)) // TODO::Fix issue in case of local and utc diff + DateTimeTz.local( + oldDateTime.local.copyDayOfMonth(year = Year(newValue)), + oldDateTime.offset + ) } } } diff --git a/triggers/timer/src/jvmMain/kotlin/Plugin.kt b/triggers/timer/src/jvmMain/kotlin/Plugin.kt index dbf4100..f0ebf38 100644 --- a/triggers/timer/src/jvmMain/kotlin/Plugin.kt +++ b/triggers/timer/src/jvmMain/kotlin/Plugin.kt @@ -1,11 +1,49 @@ package dev.inmo.plaguposter.triggers.timer +import com.soywiz.klock.DateTime +import dev.inmo.micro_utils.coroutines.runCatchingSafely import dev.inmo.plagubot.Plugin +import dev.inmo.plaguposter.posts.repo.ReadPostsRepo +import dev.inmo.tgbotapi.extensions.api.edit.edit +import dev.inmo.tgbotapi.extensions.api.send.send +import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext +import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onCommand import kotlinx.serialization.json.* import org.jetbrains.exposed.sql.Database +import org.koin.core.Koin import org.koin.core.module.Module object Plugin : Plugin { override fun Module.setupDI(database: Database, params: JsonObject) { } + + override suspend fun BehaviourContext.setupBotPlugin(koin: Koin) { + val postsRepo = koin.get() + with(ButtonsBuilder) { + includeKeyboardHandling() + } + onCommand("test") { + val reply = it.replyTo ?: return@onCommand + val postId = postsRepo.getIdByChatAndMessage( + reply.chat.id, + reply.messageId + ) ?: return@onCommand + val buttons = ButtonsBuilder.buildTimerButtons( + postId, + DateTime.nowLocal() + ) + runCatchingSafely { + edit( + it, + buttons + ) + }.onFailure { _ -> + send( + it.chat, + "Buttons", + replyMarkup = buttons + ) + } + } + } }