Merge pull request #6404 from osmandapp/TelegramImprovements

Fix sending several messages with poor internet connection
This commit is contained in:
Alexey 2018-12-28 17:29:42 +03:00 committed by GitHub
commit bba16bc5f3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 126 additions and 61 deletions

View file

@ -242,10 +242,14 @@ class TelegramSettings(private val app: TelegramApplication) {
val content = message.content
if (shareChatInfo != null) {
when (content) {
is TdApi.MessageLocation -> shareChatInfo.currentMapMessageId = message.id
is TdApi.MessageLocation -> {
shareChatInfo.currentMapMessageId = message.id
shareChatInfo.pendingMapMessage = false
}
is TdApi.MessageText -> {
shareChatInfo.currentTextMessageId = message.id
shareChatInfo.updateTextMessageId++
shareChatInfo.pendingTextMessage = false
}
}
shareChatInfo.lastSuccessfulSendTimeMs = Math.max(message.editDate, message.date) * 1000L
@ -526,6 +530,8 @@ class TelegramSettings(private val app: TelegramApplication) {
obj.put(ShareChatInfo.USER_SET_LIVE_PERIOD_KEY, chatInfo.userSetLivePeriod)
obj.put(ShareChatInfo.USER_SET_LIVE_PERIOD_START_KEY, chatInfo.userSetLivePeriodStart)
obj.put(ShareChatInfo.LAST_SUCCESSFUL_SEND_TIME_KEY, chatInfo.lastSuccessfulSendTimeMs)
obj.put(ShareChatInfo.LAST_SEND_MAP_TIME_KEY, chatInfo.lastSendMapMessageTime)
obj.put(ShareChatInfo.LAST_SEND_TEXT_TIME_KEY, chatInfo.lastSendTextMessageTime)
jArray.put(obj)
}
jArray
@ -550,6 +556,8 @@ class TelegramSettings(private val app: TelegramApplication) {
userSetLivePeriod = obj.optLong(ShareChatInfo.USER_SET_LIVE_PERIOD_KEY)
userSetLivePeriodStart = obj.optLong(ShareChatInfo.USER_SET_LIVE_PERIOD_START_KEY)
lastSuccessfulSendTimeMs = obj.optLong(ShareChatInfo.LAST_SUCCESSFUL_SEND_TIME_KEY)
lastSendMapMessageTime = obj.optInt(ShareChatInfo.LAST_SEND_MAP_TIME_KEY)
lastSendTextMessageTime = obj.optInt(ShareChatInfo.LAST_SEND_TEXT_TIME_KEY)
}
shareChatsInfo[shareInfo.chatId] = shareInfo
}
@ -833,9 +841,14 @@ class TelegramSettings(private val app: TelegramApplication) {
var userSetLivePeriod = -1L
var userSetLivePeriodStart = -1L
var lastSuccessfulSendTimeMs = -1L
var shouldDeletePreviousMessage = false
var lastSendTextMessageTime = -1
var lastSendMapMessageTime = -1
var pendingTextMessage = false
var pendingMapMessage = false
var shouldSendViaBotMessage = false
var hasSharingError = false
var shouldDeletePreviousMapMessage = false
var shouldDeletePreviousTextMessage = false
var additionalActiveTime = ADDITIONAL_ACTIVE_TIME_VALUES_SEC[0]
fun getNextAdditionalActiveTime(): Long {
@ -864,6 +877,8 @@ class TelegramSettings(private val app: TelegramApplication) {
internal const val USER_SET_LIVE_PERIOD_KEY = "userSetLivePeriod"
internal const val USER_SET_LIVE_PERIOD_START_KEY = "userSetLivePeriodStart"
internal const val LAST_SUCCESSFUL_SEND_TIME_KEY = "lastSuccessfulSendTime"
internal const val LAST_SEND_MAP_TIME_KEY = "lastSendMapMessageTime"
internal const val LAST_SEND_TEXT_TIME_KEY = "lastSendTextMessageTime"
}
}
}

View file

@ -101,14 +101,16 @@ class ShareLocationHelper(private val app: TelegramApplication) {
livePeriod
}
livePeriod = newLivePeriod
shouldDeletePreviousMessage = true
shouldDeletePreviousMapMessage = true
shouldDeletePreviousTextMessage = true
currentMessageLimit = currentTime + Math.min(newLivePeriod, TelegramHelper.MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC.toLong())
}
}
shareInfo.userSetLivePeriod != shareInfo.livePeriod
&& (shareInfo.userSetLivePeriodStart + USER_SET_LIVE_PERIOD_DELAY_MS) > currentTime -> {
shareInfo.apply {
shouldDeletePreviousMessage = true
shouldDeletePreviousMapMessage = true
shouldDeletePreviousTextMessage = true
livePeriod = shareInfo.userSetLivePeriod
currentMessageLimit = currentTime + Math.min(livePeriod, TelegramHelper.MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC.toLong())
}

View file

@ -66,6 +66,8 @@ class TelegramHelper private constructor() {
const val MIN_LOCATION_MESSAGE_LIVE_PERIOD_SEC = 61
const val MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC = 60 * 60 * 24 - 1 // one day
const val SEND_NEW_MESSAGE_INTERVAL_SEC = 10 * 60 // 10 minutes
private var helper: TelegramHelper? = null
val instance: TelegramHelper
@ -550,7 +552,7 @@ class TelegramHelper private constructor() {
resultArticles.forEach {
client?.send(TdApi.SendInlineQueryResultMessage(shareInfo.chatId, 0, true,
true, inlineQueryResults.inlineQueryId, it.id)) { obj ->
handleLiveLocationMessageUpdate(obj, shareInfo)
handleTextLocationMessageUpdate(obj, shareInfo)
}
}
}
@ -642,14 +644,9 @@ class TelegramHelper private constructor() {
when (obj.constructor) {
TdApi.Error.CONSTRUCTOR -> {
val error = obj as TdApi.Error
needRefreshActiveLiveLocationMessages = true
if (error.code == MESSAGE_CANNOT_BE_EDITED_ERROR_CODE) {
shareInfo.shouldDeletePreviousMessage = true
} else if (error.code != IGNORED_ERROR_CODE) {
if (error.code != IGNORED_ERROR_CODE) {
shareInfo.hasSharingError = true
outgoingMessagesListeners.forEach {
it.onSendLiveLocationError(error.code, error.message)
}
listener?.onTelegramError(error.code, error.message)
}
}
TdApi.Chat.CONSTRUCTOR -> {
@ -745,7 +742,7 @@ class TelegramHelper private constructor() {
if (shareInfo.currentMapMessageId != -1L && shareInfo.chatId != -1L) {
client?.send(
TdApi.EditMessageLiveLocation(shareInfo.chatId, shareInfo.currentMapMessageId, null, null)) { obj ->
handleLiveLocationMessageUpdate(obj, shareInfo)
handleMapLocationMessageUpdate(obj, shareInfo)
}
}
needRefreshActiveLiveLocationMessages = true
@ -795,10 +792,11 @@ class TelegramHelper private constructor() {
val array = LongArray(1)
if (content is TdApi.InputMessageLocation) {
array[0] = shareInfo.currentMapMessageId
} else if (content is TdApi.InputMessageLocation) {
} else if (content is TdApi.InputMessageText) {
array[0] = shareInfo.currentTextMessageId
}
if (array[0] != 0L) {
log.debug("recreateLiveLocationMessage - ${array[0]}")
client?.send(TdApi.DeleteMessages(shareInfo.chatId, array, true)) { obj ->
when (obj.constructor) {
TdApi.Ok.CONSTRUCTOR -> sendNewLiveLocationMessage(shareInfo, content)
@ -820,10 +818,10 @@ class TelegramHelper private constructor() {
private fun sendNewLiveLocationMessage(shareInfo: TelegramSettings.ShareChatInfo, content: TdApi.InputMessageContent) {
needRefreshActiveLiveLocationMessages = true
log.info("sendNewLiveLocationMessage")
log.debug("sendNewLiveLocationMessage")
client?.send(
TdApi.SendMessage(shareInfo.chatId, 0, false, true, null, content)) { obj ->
handleLiveLocationMessageUpdate(obj, shareInfo)
handleMapLocationMessageUpdate(obj, shareInfo)
}
}
@ -841,57 +839,26 @@ class TelegramHelper private constructor() {
}
val content = TdApi.InputMessageLocation(location, livePeriod)
val msgId = shareInfo.currentMapMessageId
val timeAfterLastSendMessage = ((System.currentTimeMillis() / 1000) - shareInfo.lastSendMapMessageTime)
log.debug("sendLiveLocationImpl - $msgId pendingMapMessage ${shareInfo.pendingMapMessage}")
if (msgId != -1L) {
if (shareInfo.shouldDeletePreviousMessage) {
if (shareInfo.shouldDeletePreviousMapMessage) {
recreateLiveLocationMessage(shareInfo, content)
shareInfo.shouldDeletePreviousMessage = false
shareInfo.shouldDeletePreviousMapMessage = false
shareInfo.currentMapMessageId = -1
} else {
log.info("EditMessageLiveLocation - $msgId")
log.debug("EditMessageLiveLocation - $msgId")
client?.send(
TdApi.EditMessageLiveLocation(chatId, msgId, null, location)) { obj ->
handleLiveLocationMessageUpdate(obj, shareInfo)
handleMapLocationMessageUpdate(obj, shareInfo)
}
}
} else {
} else if (!shareInfo.pendingMapMessage || shareInfo.pendingMapMessage && timeAfterLastSendMessage > SEND_NEW_MESSAGE_INTERVAL_SEC) {
sendNewLiveLocationMessage(shareInfo, content)
}
}
}
private fun handleLiveLocationMessageUpdate(obj: TdApi.Object, shareInfo: TelegramSettings.ShareChatInfo) {
when (obj.constructor) {
TdApi.Error.CONSTRUCTOR -> {
val error = obj as TdApi.Error
needRefreshActiveLiveLocationMessages = true
if (error.code == MESSAGE_CANNOT_BE_EDITED_ERROR_CODE) {
shareInfo.shouldDeletePreviousMessage = true
} else if (error.code != IGNORED_ERROR_CODE) {
shareInfo.hasSharingError = true
outgoingMessagesListeners.forEach {
it.onSendLiveLocationError(error.code, error.message)
}
}
}
TdApi.Message.CONSTRUCTOR -> {
if (obj is TdApi.Message) {
if (obj.sendingState?.constructor == TdApi.MessageSendingStateFailed.CONSTRUCTOR) {
shareInfo.hasSharingError = true
needRefreshActiveLiveLocationMessages = true
outgoingMessagesListeners.forEach {
it.onSendLiveLocationError(-1, "Live location message ${obj.id} failed to send")
}
} else {
shareInfo.hasSharingError = false
outgoingMessagesListeners.forEach {
it.onUpdateMessages(listOf(obj))
}
}
}
}
}
}
fun sendLiveLocationText(chatsShareInfo: Map<Long, TelegramSettings.ShareChatInfo>, location: Location) {
chatsShareInfo.forEach { (chatId, shareInfo) ->
if (shareInfo.getChatLiveMessageExpireTime() <= 0) {
@ -902,20 +869,101 @@ class TelegramHelper private constructor() {
shareInfo.updateTextMessageId = 1
}
val content = getTextMessageContent(shareInfo.updateTextMessageId, location)
val timeAfterLastSendMessage = ((System.currentTimeMillis() / 1000) - shareInfo.lastSendTextMessageTime)
log.debug("sendLiveLocationText - $msgId pendingMapMessage ${shareInfo.pendingTextMessage}")
if (msgId != -1L) {
if (shareInfo.shouldDeletePreviousMessage) {
if (shareInfo.shouldDeletePreviousTextMessage) {
recreateLiveLocationMessage(shareInfo, content)
shareInfo.shouldDeletePreviousMessage = false
shareInfo.currentTextMessageId = -1
shareInfo.updateTextMessageId = 1
shareInfo.shouldDeletePreviousTextMessage = false
} else {
client?.send(TdApi.EditMessageText(chatId, msgId, null, content)) { obj ->
handleLiveLocationMessageUpdate(obj, shareInfo)
handleTextLocationMessageUpdate(obj, shareInfo)
}
}
} else {
} else if (!shareInfo.pendingTextMessage || shareInfo.pendingTextMessage && timeAfterLastSendMessage > SEND_NEW_MESSAGE_INTERVAL_SEC) {
client?.send(TdApi.SendMessage(chatId, 0, false, false, null, content)) { obj ->
handleLiveLocationMessageUpdate(obj, shareInfo)
handleTextLocationMessageUpdate(obj, shareInfo)
}
}
}
}
private fun handleMapLocationMessageUpdate(obj: TdApi.Object, shareInfo: TelegramSettings.ShareChatInfo) {
when (obj.constructor) {
TdApi.Error.CONSTRUCTOR -> {
val error = obj as TdApi.Error
needRefreshActiveLiveLocationMessages = true
if (error.code == MESSAGE_CANNOT_BE_EDITED_ERROR_CODE) {
shareInfo.shouldDeletePreviousMapMessage = true
} else if (error.code != IGNORED_ERROR_CODE) {
shareInfo.hasSharingError = true
outgoingMessagesListeners.forEach {
it.onSendLiveLocationError(error.code, error.message)
}
}
}
TdApi.Message.CONSTRUCTOR -> {
if (obj is TdApi.Message) {
when {
obj.sendingState?.constructor == TdApi.MessageSendingStateFailed.CONSTRUCTOR -> {
shareInfo.hasSharingError = true
needRefreshActiveLiveLocationMessages = true
outgoingMessagesListeners.forEach {
it.onSendLiveLocationError(-1, "Map location message ${obj.id} failed to send")
}
}
obj.sendingState?.constructor == TdApi.MessageSendingStatePending.CONSTRUCTOR -> {
shareInfo.pendingMapMessage = true
shareInfo.lastSendMapMessageTime = obj.date
log.debug("handleMapLocationMessageUpdate - MessageSendingStatePending")
}
else -> {
shareInfo.hasSharingError = false
outgoingMessagesListeners.forEach {
it.onUpdateMessages(listOf(obj))
}
}
}
}
}
}
}
private fun handleTextLocationMessageUpdate(obj: TdApi.Object, shareInfo: TelegramSettings.ShareChatInfo) {
when (obj.constructor) {
TdApi.Error.CONSTRUCTOR -> {
val error = obj as TdApi.Error
if (error.code == MESSAGE_CANNOT_BE_EDITED_ERROR_CODE) {
shareInfo.shouldDeletePreviousTextMessage = true
} else if (error.code != IGNORED_ERROR_CODE) {
shareInfo.hasSharingError = true
outgoingMessagesListeners.forEach {
it.onSendLiveLocationError(error.code, error.message)
}
}
}
TdApi.Message.CONSTRUCTOR -> {
if (obj is TdApi.Message) {
when {
obj.sendingState?.constructor == TdApi.MessageSendingStateFailed.CONSTRUCTOR -> {
shareInfo.hasSharingError = true
needRefreshActiveLiveLocationMessages = true
outgoingMessagesListeners.forEach {
it.onSendLiveLocationError(-1, "Text location message ${obj.id} failed to send")
}
}
obj.sendingState?.constructor == TdApi.MessageSendingStatePending.CONSTRUCTOR -> {
shareInfo.pendingTextMessage = true
shareInfo.lastSendTextMessageTime = obj.date
log.debug("handleTextLocationMessageUpdate - MessageSendingStatePending")
}
else -> {
shareInfo.hasSharingError = false
outgoingMessagesListeners.forEach {
it.onUpdateMessages(listOf(obj))
}
}
}
}
}
}