tgbotapi/tgbotapi.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/LiveLocationProvider.kt

317 lines
10 KiB
Kotlin
Raw Normal View History

package dev.inmo.tgbotapi.extensions.api
2020-02-15 09:33:04 +00:00
2023-05-27 12:19:14 +00:00
import korlibs.time.DateTime
import korlibs.time.TimeSpan
import dev.inmo.micro_utils.coroutines.LinkedSupervisorJob
import dev.inmo.micro_utils.coroutines.launchSafelyWithoutExceptions
import dev.inmo.tgbotapi.abstracts.types.WithReplyMarkup
2020-10-04 11:06:30 +00:00
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.extensions.api.edit.edit
import dev.inmo.tgbotapi.extensions.api.edit.location.live.editLiveLocation
import dev.inmo.tgbotapi.extensions.api.edit.location.live.stopLiveLocation
import dev.inmo.tgbotapi.extensions.api.send.send
import dev.inmo.tgbotapi.extensions.api.send.sendLiveLocation
2020-11-05 18:12:14 +00:00
import dev.inmo.tgbotapi.requests.send.SendLiveLocation
2020-10-04 11:06:30 +00:00
import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
2022-04-21 18:16:41 +00:00
import dev.inmo.tgbotapi.types.chat.Chat
2020-11-05 18:12:14 +00:00
import dev.inmo.tgbotapi.types.location.LiveLocation
import dev.inmo.tgbotapi.types.location.Location
2020-11-05 18:12:14 +00:00
import dev.inmo.tgbotapi.types.location.StaticLocation
2020-10-04 11:06:30 +00:00
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
import dev.inmo.tgbotapi.types.message.abstracts.Message
import dev.inmo.tgbotapi.types.message.content.LocationContent
import dev.inmo.tgbotapi.utils.extensions.threadIdOrNull
import io.ktor.utils.io.core.Closeable
2020-02-15 09:33:04 +00:00
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.currentCoroutineContext
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import kotlin.js.JsName
import kotlin.jvm.JvmName
2020-02-15 09:33:04 +00:00
import kotlin.math.ceil
2020-10-04 10:47:30 +00:00
val defaultLivePeriodDelayMillis = (livePeriodLimit.last - 60L) * 1000L
2021-08-22 04:53:12 +00:00
/**
* @see startLiveLocation
*/
2020-11-05 17:48:23 +00:00
class LiveLocationProvider internal constructor(
private val requestsExecutor: TelegramBot,
scope: CoroutineScope,
autoCloseTimeDelay: Double,
initMessage: ContentMessage<LocationContent>
) : Closeable {
private val doWhenClose = {
scope.launch {
requestsExecutor.stopLiveLocation(message)
}
}
private val autoCloseTime = DateTime.now() + TimeSpan(autoCloseTimeDelay)
val leftUntilCloseMillis: TimeSpan
get() = autoCloseTime - DateTime.now()
var isClosed: Boolean = false
private set
get() = field || leftUntilCloseMillis.millisecondsLong < 0L
var message: ContentMessage<LocationContent> = initMessage
private set
2020-11-05 17:48:23 +00:00
val lastLocation: LiveLocation
get() = message.content.location as LiveLocation
2021-10-01 13:38:22 +00:00
/**
* @param replyMarkup Some [InlineKeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard]
* as a builder for that
*/
suspend fun updateLocation(
2020-11-05 17:48:23 +00:00
location: LiveLocation,
replyMarkup: InlineKeyboardMarkup? = null
2020-11-05 17:48:23 +00:00
): LiveLocation {
if (!isClosed) {
message = requestsExecutor.editLiveLocation(
message,
location,
replyMarkup
)
return lastLocation
} else {
error("LiveLocation is closed")
}
}
override fun close() {
if (isClosed) {
return
}
isClosed = true
doWhenClose()
}
}
2020-02-15 09:33:04 +00:00
2021-10-01 13:38:22 +00:00
/**
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
* [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param
*/
suspend fun TelegramBot.startLiveLocation(
2020-02-15 09:33:04 +00:00
scope: CoroutineScope,
chatId: ChatIdentifier,
latitude: Double,
longitude: Double,
2020-10-04 10:47:30 +00:00
liveTimeMillis: Long = defaultLivePeriodDelayMillis,
2020-11-05 17:48:23 +00:00
initHorizontalAccuracy: Meters? = null,
initHeading: Degrees? = null,
initProximityAlertRadius: Meters? = null,
threadId: MessageThreadId? = chatId.threadId,
2020-02-15 09:33:04 +00:00
disableNotification: Boolean = false,
2022-01-01 14:13:22 +00:00
protectContent: Boolean = false,
replyToMessageId: MessageId? = null,
2020-11-05 17:48:23 +00:00
allowSendingWithoutReply: Boolean? = null,
2020-02-15 09:33:04 +00:00
replyMarkup: KeyboardMarkup? = null
2020-11-05 17:48:23 +00:00
): LiveLocationProvider {
2020-02-15 09:33:04 +00:00
val liveTimeAsDouble = liveTimeMillis.toDouble()
val locationMessage = execute(
2020-11-05 17:48:23 +00:00
SendLiveLocation(
2020-02-15 09:33:04 +00:00
chatId,
latitude,
longitude,
2020-11-05 17:48:23 +00:00
ceil(liveTimeAsDouble / 1000).toInt(),
initHorizontalAccuracy,
initHeading,
initProximityAlertRadius,
2022-11-07 18:11:14 +00:00
threadId,
2020-02-15 09:33:04 +00:00
disableNotification,
2022-01-01 14:13:22 +00:00
protectContent,
2020-02-15 09:33:04 +00:00
replyToMessageId,
2020-11-05 17:48:23 +00:00
allowSendingWithoutReply,
2020-02-15 09:33:04 +00:00
replyMarkup
)
)
2020-11-05 17:48:23 +00:00
return LiveLocationProvider(
2020-02-15 09:33:04 +00:00
this,
scope,
liveTimeAsDouble,
locationMessage
)
}
2021-10-01 13:38:22 +00:00
/**
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
* [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param
*/
suspend fun TelegramBot.startLiveLocation(
2020-02-15 09:33:04 +00:00
scope: CoroutineScope,
chat: Chat,
latitude: Double,
longitude: Double,
2020-10-04 10:47:30 +00:00
liveTimeMillis: Long = defaultLivePeriodDelayMillis,
2020-11-05 17:48:23 +00:00
initHorizontalAccuracy: Meters? = null,
initHeading: Degrees? = null,
initProximityAlertRadius: Meters? = null,
threadId: MessageThreadId? = chat.id.threadId,
2020-02-15 09:33:04 +00:00
disableNotification: Boolean = false,
2022-01-01 14:13:22 +00:00
protectContent: Boolean = false,
replyToMessageId: MessageId? = null,
2020-11-05 17:48:23 +00:00
allowSendingWithoutReply: Boolean? = null,
2020-02-15 09:33:04 +00:00
replyMarkup: KeyboardMarkup? = null
2020-11-05 17:48:23 +00:00
): LiveLocationProvider = startLiveLocation(
scope,
chat.id,
latitude,
longitude,
liveTimeMillis,
initHorizontalAccuracy,
initHeading,
initProximityAlertRadius,
2022-11-07 18:11:14 +00:00
threadId,
2020-11-05 17:48:23 +00:00
disableNotification,
2022-01-01 14:13:22 +00:00
protectContent,
2020-11-05 17:48:23 +00:00
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
2020-02-15 09:33:04 +00:00
)
2021-10-01 13:38:22 +00:00
/**
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
* [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param
*/
suspend fun TelegramBot.startLiveLocation(
2020-02-15 09:33:04 +00:00
scope: CoroutineScope,
2022-11-10 09:56:38 +00:00
chatId: IdChatIdentifier,
2020-11-04 19:12:14 +00:00
location: StaticLocation,
2020-10-04 10:47:30 +00:00
liveTimeMillis: Long = defaultLivePeriodDelayMillis,
2020-11-05 17:48:23 +00:00
initHorizontalAccuracy: Meters? = null,
initHeading: Degrees? = null,
initProximityAlertRadius: Meters? = null,
threadId: MessageThreadId? = chatId.threadId,
2020-02-15 09:33:04 +00:00
disableNotification: Boolean = false,
2022-01-01 14:13:22 +00:00
protectContent: Boolean = false,
replyToMessageId: MessageId? = null,
2020-11-05 17:48:23 +00:00
allowSendingWithoutReply: Boolean? = null,
2020-02-15 09:33:04 +00:00
replyMarkup: KeyboardMarkup? = null
2020-11-05 17:48:23 +00:00
): LiveLocationProvider = startLiveLocation(
scope,
chatId,
location.latitude,
location.longitude,
liveTimeMillis,
initHorizontalAccuracy,
initHeading,
initProximityAlertRadius,
2022-11-07 18:11:14 +00:00
threadId,
2020-11-05 17:48:23 +00:00
disableNotification,
2022-01-01 14:13:22 +00:00
protectContent,
2020-11-05 17:48:23 +00:00
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
2020-02-15 09:33:04 +00:00
)
2021-10-01 13:38:22 +00:00
/**
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
* [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param
*/
suspend fun TelegramBot.startLiveLocation(
2020-02-15 09:33:04 +00:00
scope: CoroutineScope,
chat: Chat,
2020-11-04 19:12:14 +00:00
location: StaticLocation,
2020-10-04 10:47:30 +00:00
liveTimeMillis: Long = defaultLivePeriodDelayMillis,
2020-11-05 17:48:23 +00:00
initHorizontalAccuracy: Meters? = null,
initHeading: Degrees? = null,
initProximityAlertRadius: Meters? = null,
threadId: MessageThreadId? = chat.id.threadId,
2020-02-15 09:33:04 +00:00
disableNotification: Boolean = false,
2022-01-01 14:13:22 +00:00
protectContent: Boolean = false,
replyToMessageId: MessageId? = null,
2020-11-05 17:48:23 +00:00
allowSendingWithoutReply: Boolean? = null,
2020-02-15 09:33:04 +00:00
replyMarkup: KeyboardMarkup? = null
2020-11-05 17:48:23 +00:00
): LiveLocationProvider = startLiveLocation(
scope,
chat.id,
location.latitude,
location.longitude,
liveTimeMillis,
initHorizontalAccuracy,
initHeading,
initProximityAlertRadius,
2022-11-07 18:11:14 +00:00
threadId,
2020-11-05 17:48:23 +00:00
disableNotification,
2022-01-01 14:13:22 +00:00
protectContent,
2020-11-05 17:48:23 +00:00
replyToMessageId,
allowSendingWithoutReply,
replyMarkup
2020-02-15 09:33:04 +00:00
)
2020-10-04 10:47:30 +00:00
2021-10-01 13:38:22 +00:00
/**
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
* [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param
*/
2020-10-04 10:47:30 +00:00
suspend inline fun TelegramBot.replyWithLiveLocation(
to: Message,
scope: CoroutineScope,
latitude: Double,
longitude: Double,
liveTimeMillis: Long = defaultLivePeriodDelayMillis,
2020-11-05 17:48:23 +00:00
initHorizontalAccuracy: Meters? = null,
initHeading: Degrees? = null,
initProximityAlertRadius: Meters? = null,
threadId: MessageThreadId? = to.threadIdOrNull,
2020-10-04 10:47:30 +00:00
disableNotification: Boolean = false,
2022-01-01 14:13:22 +00:00
protectContent: Boolean = false,
2020-11-05 17:48:23 +00:00
allowSendingWithoutReply: Boolean? = null,
2020-10-04 10:47:30 +00:00
replyMarkup: KeyboardMarkup? = null
2020-11-05 17:48:23 +00:00
) = startLiveLocation(
scope,
to.chat,
latitude,
longitude,
liveTimeMillis,
initHorizontalAccuracy,
initHeading,
initProximityAlertRadius,
2022-11-07 18:11:14 +00:00
threadId,
2020-11-05 17:48:23 +00:00
disableNotification,
2022-01-01 14:13:22 +00:00
protectContent,
2020-11-05 17:48:23 +00:00
to.messageId,
allowSendingWithoutReply,
replyMarkup
)
2020-10-04 10:47:30 +00:00
2021-10-01 13:38:22 +00:00
/**
* @param replyMarkup Some of [KeyboardMarkup]. See [dev.inmo.tgbotapi.extensions.utils.types.buttons.replyKeyboard] or
* [dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard] as a builders for that param
*/
2020-10-04 10:47:30 +00:00
suspend inline fun TelegramBot.replyWithLiveLocation(
to: Message,
scope: CoroutineScope,
2020-11-04 19:12:14 +00:00
location: StaticLocation,
2020-10-04 10:47:30 +00:00
liveTimeMillis: Long = defaultLivePeriodDelayMillis,
2020-11-05 17:48:23 +00:00
initHorizontalAccuracy: Meters? = null,
initHeading: Degrees? = null,
initProximityAlertRadius: Meters? = null,
threadId: MessageThreadId? = to.threadIdOrNull,
2020-10-04 10:47:30 +00:00
disableNotification: Boolean = false,
2022-01-01 14:13:22 +00:00
protectContent: Boolean = false,
2020-11-05 17:48:23 +00:00
allowSendingWithoutReply: Boolean? = null,
2020-10-04 10:47:30 +00:00
replyMarkup: KeyboardMarkup? = null
2020-11-05 17:48:23 +00:00
) = startLiveLocation(
scope,
to.chat,
location,
liveTimeMillis,
initHorizontalAccuracy,
initHeading,
initProximityAlertRadius,
2022-11-07 18:11:14 +00:00
threadId,
2020-11-05 17:48:23 +00:00
disableNotification,
2022-01-01 14:13:22 +00:00
protectContent,
2020-11-05 17:48:23 +00:00
to.messageId,
allowSendingWithoutReply,
replyMarkup
)