db refactoring continues
This commit is contained in:
parent
430ceb10ae
commit
256df2c866
9 changed files with 348 additions and 281 deletions
|
@ -13,6 +13,7 @@ import android.os.*
|
|||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import net.osmand.PlatformUtil
|
||||
import net.osmand.telegram.helpers.LocationMessages
|
||||
import net.osmand.telegram.helpers.LocationMessages.LocationMessage
|
||||
import net.osmand.telegram.helpers.TelegramHelper.TelegramIncomingMessagesListener
|
||||
import net.osmand.telegram.helpers.TelegramHelper.TelegramOutgoingMessagesListener
|
||||
|
@ -277,7 +278,7 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
|
|||
override fun onReceiveChatLocationMessages(chatId: Long, vararg messages: TdApi.Message) {
|
||||
app().showLocationHelper.startShowMessagesTask(chatId, *messages)
|
||||
messages.forEach {
|
||||
val locationMessage = OsmandLocationUtils.parseMessage(it, app().telegramHelper, LocationMessage.STATUS_PREPARED)
|
||||
val locationMessage = OsmandLocationUtils.parseMessage(it, app().telegramHelper, LocationMessages.STATUS_PREPARED)
|
||||
if (locationMessage != null) {
|
||||
app().locationMessages.addIngoingMessage(locationMessage)
|
||||
}
|
||||
|
|
|
@ -845,13 +845,15 @@ class TelegramSettings(private val app: TelegramApplication) {
|
|||
var updateTextMessageId = 1
|
||||
var currentMessageLimit = -1L
|
||||
var currentMapMessageId = -1L
|
||||
var oldMapMessageId = -1L
|
||||
var currentTextMessageId = -1L
|
||||
var oldTextMessageId = -1L
|
||||
var userSetLivePeriod = -1L
|
||||
var userSetLivePeriodStart = -1L
|
||||
var lastSuccessfulSendTimeMs = -1L
|
||||
var lastSendTextMessageTime = -1
|
||||
var lastSendMapMessageTime = -1
|
||||
var bufferedMessages = 0
|
||||
var pendingTdLib = 0
|
||||
var pendingTextMessage = false
|
||||
var pendingMapMessage = false
|
||||
var shouldSendViaBotMessage = false
|
||||
|
|
|
@ -11,7 +11,7 @@ import kotlin.collections.ArrayList
|
|||
class LocationMessages(val app: TelegramApplication) {
|
||||
|
||||
// todo - bufferedMessages is for prepared/pending messages only. On app start we read prepared/pending messages to bufferedMessages. After status changed to sent/error - remove message from buffered.
|
||||
private var bufferedMessages = emptyList<LocationMessage>()
|
||||
private var bufferedMessages = emptyList<BufferMessage>()
|
||||
|
||||
private val dbHelper: SQLiteHelper
|
||||
|
||||
|
@ -20,27 +20,23 @@ class LocationMessages(val app: TelegramApplication) {
|
|||
readBufferedMessages()
|
||||
}
|
||||
|
||||
fun getPreparedMessages(): List<LocationMessage> {
|
||||
val currentUserId = app.telegramHelper.getCurrentUserId()
|
||||
return bufferedMessages.filter { it.userId == currentUserId && it.status == LocationMessage.STATUS_PREPARED }.sortedBy { it.date }
|
||||
fun getPreparedMessages(): List<BufferMessage> {
|
||||
return bufferedMessages.sortedBy { it.date }
|
||||
}
|
||||
|
||||
// todo - drop method. add collected / sent messages count to ShareChatInfo
|
||||
fun getOutgoingMessages(chatId: Long): List<LocationMessage> {
|
||||
val currentUserId = app.telegramHelper.getCurrentUserId()
|
||||
return bufferedMessages.filter { it.userId == currentUserId && it.chatId == chatId }.sortedBy { it.date }
|
||||
}
|
||||
// // todo - drop method. add collected / sent messages count to ShareChatInfo
|
||||
// fun getOutgoingMessages(chatId: Long): List<LocationMessage> {
|
||||
// val currentUserId = app.telegramHelper.getCurrentUserId()
|
||||
// return bufferedMessages.filter { it.userId == currentUserId && it.chatId == chatId }.sortedBy { it.date }
|
||||
// }
|
||||
|
||||
// todo - drop it or read from db
|
||||
fun getSentMessages(chatId: Long, date:Long): List<LocationMessage> {
|
||||
val currentUserId = app.telegramHelper.getCurrentUserId()
|
||||
return bufferedMessages.filter { it.userId == currentUserId && it.chatId == chatId && it.date > date }.sortedBy { it.date }
|
||||
}
|
||||
|
||||
// todo - drop it or read from db
|
||||
fun getSentMessages(chatId: Long): List<LocationMessage> {
|
||||
val currentUserId = app.telegramHelper.getCurrentUserId()
|
||||
return bufferedMessages.filter { it.userId == currentUserId && it.chatId == chatId && it.status == LocationMessage.STATUS_SENT }.sortedBy { it.date }
|
||||
fun updateBufferedMessageStatus(oldMessage: BufferMessage, status: Int){
|
||||
val messages = mutableListOf(*this.bufferedMessages.toTypedArray())
|
||||
messages.remove(oldMessage)
|
||||
val newMessage = BufferMessage(oldMessage.chatId,oldMessage.lat,oldMessage.lon,oldMessage.altitude,oldMessage.speed,oldMessage.hdop,oldMessage.bearing,oldMessage.date,oldMessage.type,status)
|
||||
messages.add(newMessage)
|
||||
this.bufferedMessages = messages
|
||||
// dbHelper.addBufferedMessage(newMessage)
|
||||
}
|
||||
|
||||
// todo - read from db by date (Victor's suggestion - filter by one day only. Need to be changed in UI also.
|
||||
|
@ -48,73 +44,78 @@ class LocationMessages(val app: TelegramApplication) {
|
|||
return emptyList()
|
||||
}
|
||||
|
||||
fun addOutgoingMessage(message: LocationMessage) {
|
||||
fun addBufferedMessage(message: BufferMessage) {
|
||||
val messages = mutableListOf(*this.bufferedMessages.toTypedArray())
|
||||
messages.add(message)
|
||||
this.bufferedMessages = messages
|
||||
dbHelper.addOutgoingMessage(message)
|
||||
dbHelper.addBufferedMessage(message)
|
||||
}
|
||||
|
||||
fun addIngoingMessage(message: LocationMessage) {
|
||||
dbHelper.addIngoingMessage(message)
|
||||
}
|
||||
|
||||
fun clearOutgoingMessages() {
|
||||
dbHelper.clearOutgoingMessages()
|
||||
fun clearBufferedMessages() {
|
||||
dbHelper.clearBufferedMessages()
|
||||
bufferedMessages = emptyList()
|
||||
}
|
||||
|
||||
// todo - both methods should be refactored since we have two tables now for outgoing/ingoing messages. Data should be read from db.
|
||||
fun collectRecordedDataForUser(userId: Int, chatId: Long, start: Long, end: Long): List<LocationMessage> {
|
||||
return if (chatId == 0L) {
|
||||
bufferedMessages.sortedWith(compareBy({ it.userId }, { it.chatId })).filter { it.userId == userId && it.date in (start + 1)..(end - 1) }
|
||||
} else {
|
||||
bufferedMessages.sortedWith(compareBy({ it.userId }, { it.chatId })).filter {
|
||||
it.chatId == chatId && it.userId == userId && it.status == LocationMessage.STATUS_SENT && it.date in (start + 1)..(end - 1) }
|
||||
}
|
||||
}
|
||||
|
||||
fun collectRecordedDataForUsers(start: Long, end: Long, ignoredUsersIds: ArrayList<Int>): List<LocationMessage> {
|
||||
return bufferedMessages.sortedWith(compareBy({ it.userId }, { it.chatId })).filter {
|
||||
it.date in (start + 1)..(end - 1) && !ignoredUsersIds.contains(it.userId)
|
||||
}
|
||||
}
|
||||
// fun collectRecordedDataForUser(userId: Int, chatId: Long, start: Long, end: Long): List<LocationMessage> {
|
||||
// return if (chatId == 0L) {
|
||||
// bufferedMessages.sortedWith(compareBy({ it.userId }, { it.chatId })).filter { it.userId == userId && it.date in (start + 1)..(end - 1) }
|
||||
// } else {
|
||||
// bufferedMessages.sortedWith(compareBy({ it.userId }, { it.chatId })).filter {
|
||||
// it.chatId == chatId && it.userId == userId&&it.date in (start + 1)..(end - 1) }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// fun collectRecordedDataForUsers(start: Long, end: Long, ignoredUsersIds: ArrayList<Int>): List<LocationMessage> {
|
||||
// return bufferedMessages.sortedWith(compareBy({ it.userId }, { it.chatId })).filter {
|
||||
// it.date in (start + 1)..(end - 1) && !ignoredUsersIds.contains(it.userId)
|
||||
// }
|
||||
// }
|
||||
|
||||
private fun readBufferedMessages() {
|
||||
this.bufferedMessages = dbHelper.getOutgoingMessages();
|
||||
this.bufferedMessages = dbHelper.getBufferedMessages()
|
||||
}
|
||||
|
||||
private class SQLiteHelper(context: Context) :
|
||||
SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) {
|
||||
|
||||
override fun onCreate(db: SQLiteDatabase) {
|
||||
db.execSQL(OUTGOING_TABLE_CREATE)
|
||||
db.execSQL("CREATE INDEX $DATE_INDEX ON $OUTGOING_TABLE_NAME (\"$COL_DATE\" DESC);")
|
||||
db.execSQL(INGOING_TABLE_CREATE)
|
||||
db.execSQL("CREATE INDEX $DATE_INDEX ON $INGOING_TABLE_NAME (\"$COL_DATE\" DESC);")
|
||||
db.execSQL(TIMELINE_TABLE_CREATE)
|
||||
db.execSQL("CREATE INDEX $DATE_INDEX ON $TIMELINE_TABLE_NAME (\"$COL_TIME\" DESC);")
|
||||
db.execSQL(BUFFER_TABLE_CREATE)
|
||||
}
|
||||
|
||||
override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
|
||||
db.execSQL(OUTGOING_TABLE_DELETE)
|
||||
db.execSQL(INGOING_TABLE_DELETE)
|
||||
db.execSQL(TIMELINE_TABLE_DELETE)
|
||||
db.execSQL(BUFFER_TABLE_DELETE)
|
||||
onCreate(db)
|
||||
}
|
||||
|
||||
internal fun addOutgoingMessage(message: LocationMessage) {
|
||||
writableDatabase?.execSQL(OUTGOING_TABLE_INSERT,
|
||||
arrayOf(message.userId, message.chatId, message.lat, message.lon, message.altitude, message.speed,
|
||||
message.hdop, message.bearing, message.date, message.type, message.status, message.messageId))
|
||||
internal fun addBufferedMessage(message: BufferMessage) {
|
||||
writableDatabase?.execSQL(BUFFER_TABLE_INSERT,
|
||||
arrayOf(message.chatId, message.lat, message.lon, message.altitude, message.speed,
|
||||
message.hdop, message.bearing, message.date, message.type))
|
||||
}
|
||||
|
||||
internal fun addIngoingMessage(message: LocationMessage) {
|
||||
writableDatabase?.execSQL(INGOING_TABLE_INSERT,
|
||||
writableDatabase?.execSQL(TIMELINE_TABLE_INSERT,
|
||||
arrayOf(message.userId, message.chatId, message.lat, message.lon, message.altitude, message.speed,
|
||||
message.hdop, message.bearing, message.date, message.type, message.status, message.messageId))
|
||||
message.hdop, message.bearing, message.date, message.type))
|
||||
}
|
||||
|
||||
internal fun addOutgoingMessage(message: LocationMessage) {
|
||||
writableDatabase?.execSQL(TIMELINE_TABLE_INSERT,
|
||||
arrayOf(message.userId, message.chatId, message.lat, message.lon, message.altitude, message.speed,
|
||||
message.hdop, message.bearing, message.date, message.type))
|
||||
}
|
||||
|
||||
internal fun getOutgoingMessages(): List<LocationMessage> {
|
||||
val res = arrayListOf<LocationMessage>()
|
||||
readableDatabase?.rawQuery(OUTGOING_TABLE_SELECT, null)?.apply {
|
||||
readableDatabase?.rawQuery(TIMELINE_TABLE_SELECT, null)?.apply {
|
||||
if (moveToFirst()) {
|
||||
do {
|
||||
res.add(readLocationMessage(this@apply))
|
||||
|
@ -125,6 +126,19 @@ class LocationMessages(val app: TelegramApplication) {
|
|||
return res
|
||||
}
|
||||
|
||||
internal fun getBufferedMessages(): List<BufferMessage> {
|
||||
val res = arrayListOf<BufferMessage>()
|
||||
readableDatabase?.rawQuery(BUFFER_TABLE_SELECT, null)?.apply {
|
||||
if (moveToFirst()) {
|
||||
do {
|
||||
res.add(readBufferMessage(this@apply))
|
||||
} while (moveToNext())
|
||||
}
|
||||
close()
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
internal fun readLocationMessage(cursor: Cursor): LocationMessage {
|
||||
val userId = cursor.getInt(0)
|
||||
val chatId = cursor.getLong(1)
|
||||
|
@ -136,27 +150,40 @@ class LocationMessages(val app: TelegramApplication) {
|
|||
val bearing = cursor.getDouble(7)
|
||||
val date = cursor.getLong(8)
|
||||
val type = cursor.getInt(9)
|
||||
val status = cursor.getInt(10)
|
||||
val messageId = cursor.getLong(11)
|
||||
|
||||
return LocationMessage(userId, chatId, lat, lon, altitude, speed, hdop, bearing, date, type, status, messageId)
|
||||
return LocationMessage(userId, chatId, lat, lon, altitude, speed, hdop, bearing, date, type)
|
||||
}
|
||||
|
||||
internal fun clearOutgoingMessages() {
|
||||
writableDatabase?.execSQL(OUTGOING_TABLE_CLEAR)
|
||||
internal fun readBufferMessage(cursor: Cursor): BufferMessage {
|
||||
val chatId = cursor.getLong(1)
|
||||
val lat = cursor.getDouble(2)
|
||||
val lon = cursor.getDouble(3)
|
||||
val altitude = cursor.getDouble(4)
|
||||
val speed = cursor.getDouble(5)
|
||||
val hdop = cursor.getDouble(6)
|
||||
val bearing = cursor.getDouble(7)
|
||||
val date = cursor.getLong(8)
|
||||
val type = cursor.getInt(9)
|
||||
val status = cursor.getInt(10)
|
||||
|
||||
return BufferMessage(chatId, lat, lon, altitude, speed, hdop, bearing, date, type,status)
|
||||
}
|
||||
|
||||
internal fun clearBufferedMessages() {
|
||||
writableDatabase?.execSQL(BUFFER_TABLE_CLEAR)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private const val DATABASE_NAME = "location_messages"
|
||||
private const val DATABASE_VERSION = 3
|
||||
private const val DATABASE_VERSION = 4
|
||||
|
||||
private const val OUTGOING_TABLE_NAME = "outgoing"
|
||||
private const val INGOING_TABLE_NAME = "ingoing"
|
||||
private const val TIMELINE_TABLE_NAME = "timeline"
|
||||
private const val BUFFER_TABLE_NAME = "buffer"
|
||||
|
||||
private const val COL_USER_ID = "user_id"
|
||||
private const val COL_CHAT_ID = "chat_id"
|
||||
private const val COL_DATE = "date"
|
||||
private const val COL_TIME = "time"
|
||||
private const val COL_LAT = "lat"
|
||||
private const val COL_LON = "lon"
|
||||
private const val COL_ALTITUDE = "altitude"
|
||||
|
@ -169,38 +196,49 @@ class LocationMessages(val app: TelegramApplication) {
|
|||
|
||||
private const val DATE_INDEX = "date_index"
|
||||
|
||||
// Outgoing messages table
|
||||
private const val OUTGOING_TABLE_INSERT =
|
||||
("INSERT INTO $OUTGOING_TABLE_NAME ($COL_USER_ID, $COL_CHAT_ID, $COL_LAT, $COL_LON, $COL_ALTITUDE, $COL_SPEED, $COL_HDOP, $COL_BEARING, $COL_DATE, $COL_TYPE, $COL_MESSAGE_STATUS, $COL_MESSAGE_ID) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
|
||||
// Timeline messages table
|
||||
private const val TIMELINE_TABLE_INSERT =
|
||||
("INSERT INTO $TIMELINE_TABLE_NAME ($COL_USER_ID, $COL_CHAT_ID, $COL_LAT, $COL_LON, $COL_ALTITUDE, $COL_SPEED, $COL_HDOP, $COL_BEARING, $COL_TIME, $COL_TYPE, $COL_MESSAGE_ID) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
|
||||
|
||||
private const val OUTGOING_TABLE_CREATE =
|
||||
("CREATE TABLE IF NOT EXISTS $OUTGOING_TABLE_NAME ($COL_USER_ID long, $COL_CHAT_ID long,$COL_LAT double, $COL_LON double, $COL_ALTITUDE double, $COL_SPEED float, $COL_HDOP double, $COL_BEARING double, $COL_DATE long, $COL_TYPE int, $COL_MESSAGE_STATUS int, $COL_MESSAGE_ID long )")
|
||||
private const val TIMELINE_TABLE_CREATE =
|
||||
("CREATE TABLE IF NOT EXISTS $TIMELINE_TABLE_NAME ($COL_USER_ID long, $COL_CHAT_ID long,$COL_LAT double, $COL_LON double, $COL_ALTITUDE double, $COL_SPEED float, $COL_HDOP double, $COL_BEARING double, $COL_TIME long, $COL_TYPE int, $COL_MESSAGE_ID long )")
|
||||
|
||||
private const val OUTGOING_TABLE_SELECT =
|
||||
"SELECT $COL_USER_ID, $COL_CHAT_ID, $COL_LAT, $COL_LON, $COL_ALTITUDE, $COL_SPEED, $COL_HDOP, $COL_BEARING, $COL_DATE, $COL_TYPE, $COL_MESSAGE_STATUS, $COL_MESSAGE_ID FROM $OUTGOING_TABLE_NAME"
|
||||
private const val TIMELINE_TABLE_SELECT =
|
||||
"SELECT $COL_USER_ID, $COL_CHAT_ID, $COL_LAT, $COL_LON, $COL_ALTITUDE, $COL_SPEED, $COL_HDOP, $COL_BEARING, $COL_TIME, $COL_TYPE, $COL_MESSAGE_ID FROM $TIMELINE_TABLE_NAME"
|
||||
|
||||
private const val OUTGOING_TABLE_CLEAR = "DELETE FROM $OUTGOING_TABLE_NAME"
|
||||
private const val TIMELINE_TABLE_CLEAR = "DELETE FROM $TIMELINE_TABLE_NAME"
|
||||
|
||||
private const val OUTGOING_TABLE_DELETE = "DROP TABLE IF EXISTS $OUTGOING_TABLE_NAME"
|
||||
private const val TIMELINE_TABLE_DELETE = "DROP TABLE IF EXISTS $TIMELINE_TABLE_NAME"
|
||||
|
||||
// Ingoing messages table
|
||||
private const val INGOING_TABLE_INSERT =
|
||||
("INSERT INTO $INGOING_TABLE_NAME ($COL_USER_ID, $COL_CHAT_ID, $COL_LAT, $COL_LON, $COL_ALTITUDE, $COL_SPEED, $COL_HDOP, $COL_BEARING, $COL_DATE, $COL_TYPE, $COL_MESSAGE_STATUS, $COL_MESSAGE_ID) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
|
||||
// Buffer messages table
|
||||
private const val BUFFER_TABLE_INSERT =
|
||||
("INSERT INTO $BUFFER_TABLE_NAME ($COL_CHAT_ID, $COL_LAT, $COL_LON, $COL_ALTITUDE, $COL_SPEED, $COL_HDOP, $COL_BEARING, $COL_TIME, $COL_TYPE, $COL_MESSAGE_STATUS) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
|
||||
|
||||
private const val INGOING_TABLE_CREATE =
|
||||
("CREATE TABLE IF NOT EXISTS $INGOING_TABLE_NAME ($COL_USER_ID long, $COL_CHAT_ID long,$COL_LAT double, $COL_LON double, $COL_ALTITUDE double, $COL_SPEED float, $COL_HDOP double, $COL_BEARING double, $COL_DATE long, $COL_TYPE int, $COL_MESSAGE_STATUS int, $COL_MESSAGE_ID long )")
|
||||
private const val BUFFER_TABLE_CREATE =
|
||||
("CREATE TABLE IF NOT EXISTS $BUFFER_TABLE_NAME ($COL_CHAT_ID long, $COL_LAT double, $COL_LON double, $COL_ALTITUDE double, $COL_SPEED float, $COL_HDOP double, $COL_BEARING double, $COL_TIME long, $COL_TYPE int, $COL_MESSAGE_STATUS int)")
|
||||
|
||||
private const val INGOING_TABLE_SELECT =
|
||||
"SELECT $COL_USER_ID, $COL_CHAT_ID, $COL_LAT, $COL_LON, $COL_ALTITUDE, $COL_SPEED, $COL_HDOP, $COL_BEARING, $COL_DATE, $COL_TYPE, $COL_MESSAGE_STATUS, $COL_MESSAGE_ID FROM $INGOING_TABLE_NAME"
|
||||
private const val BUFFER_TABLE_SELECT =
|
||||
"SELECT $COL_CHAT_ID, $COL_LAT, $COL_LON, $COL_ALTITUDE, $COL_SPEED, $COL_HDOP, $COL_BEARING, $COL_TIME, $COL_TYPE, $COL_MESSAGE_STATUS FROM $BUFFER_TABLE_NAME"
|
||||
|
||||
private const val INGOING_TABLE_CLEAR = "DELETE FROM $INGOING_TABLE_NAME"
|
||||
private const val BUFFER_TABLE_CLEAR = "DELETE FROM $BUFFER_TABLE_NAME"
|
||||
|
||||
private const val INGOING_TABLE_DELETE = "DROP TABLE IF EXISTS $INGOING_TABLE_NAME"
|
||||
private const val BUFFER_TABLE_DELETE = "DROP TABLE IF EXISTS $BUFFER_TABLE_NAME"
|
||||
}
|
||||
}
|
||||
|
||||
data class LocationMessage(
|
||||
val userId: Int,
|
||||
val chatId: Long,
|
||||
val lat: Double,
|
||||
val lon: Double,
|
||||
val altitude: Double,
|
||||
val speed: Double,
|
||||
val hdop: Double,
|
||||
val bearing: Double,
|
||||
val date: Long,
|
||||
val type: Int)
|
||||
|
||||
data class BufferMessage (
|
||||
val chatId: Long,
|
||||
val lat: Double,
|
||||
val lon: Double,
|
||||
|
@ -211,8 +249,7 @@ class LocationMessages(val app: TelegramApplication) {
|
|||
val date: Long,
|
||||
val type: Int,
|
||||
// todo - status and messageId should be updated in db right away. Make them val instead of var.
|
||||
var status: Int,
|
||||
var messageId: Long) {
|
||||
val status: Int)
|
||||
|
||||
companion object {
|
||||
|
||||
|
@ -227,4 +264,3 @@ class LocationMessages(val app: TelegramApplication) {
|
|||
const val TYPE_BOT_TEXT = 3
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@ package net.osmand.telegram.helpers
|
|||
import net.osmand.Location
|
||||
import net.osmand.PlatformUtil
|
||||
import net.osmand.telegram.*
|
||||
import net.osmand.telegram.helpers.LocationMessages.LocationMessage
|
||||
import net.osmand.telegram.helpers.LocationMessages.BufferMessage
|
||||
import net.osmand.telegram.notifications.TelegramNotification.NotificationType
|
||||
import net.osmand.telegram.utils.AndroidNetworkUtils
|
||||
import net.osmand.telegram.utils.BASE_URL
|
||||
|
@ -50,8 +50,7 @@ class ShareLocationHelper(private val app: TelegramApplication) {
|
|||
|
||||
if (location != null) {
|
||||
if (app.settings.getChatsShareInfo().isNotEmpty()) {
|
||||
addNewLocationMessages(location, app.telegramHelper.getCurrentUserId())
|
||||
shareMessages()
|
||||
shareLocationMessages(location, app.telegramHelper.getCurrentUserId())
|
||||
}
|
||||
lastLocationMessageSentTime = System.currentTimeMillis()
|
||||
}
|
||||
|
@ -132,58 +131,45 @@ class ShareLocationHelper(private val app: TelegramApplication) {
|
|||
refreshNotification()
|
||||
}
|
||||
|
||||
private fun addNewLocationMessages(location: Location, userId: Int) {
|
||||
private fun shareLocationMessages(location: Location, userId: Int) {
|
||||
val chatsShareInfo = app.settings.getChatsShareInfo()
|
||||
val latitude = location.latitude
|
||||
val longitude = location.longitude
|
||||
val isBot = app.settings.currentSharingMode != userId.toString()
|
||||
val sharingMode = app.settings.currentSharingMode
|
||||
val isBot = sharingMode != userId.toString()
|
||||
val types = mutableListOf<Int>()
|
||||
var bufferedMessagesFull = false
|
||||
|
||||
when (app.settings.shareTypeValue) {
|
||||
SHARE_TYPE_MAP -> {
|
||||
types.add(if (isBot) LocationMessage.TYPE_BOT_MAP else LocationMessage.TYPE_USER_MAP)
|
||||
types.add(if (isBot) LocationMessages.TYPE_BOT_MAP else LocationMessages.TYPE_USER_MAP)
|
||||
}
|
||||
SHARE_TYPE_TEXT -> {
|
||||
types.add(if (isBot) LocationMessage.TYPE_BOT_TEXT else LocationMessage.TYPE_USER_TEXT)
|
||||
types.add(if (isBot) LocationMessages.TYPE_BOT_TEXT else LocationMessages.TYPE_USER_TEXT)
|
||||
}
|
||||
SHARE_TYPE_MAP_AND_TEXT -> {
|
||||
types.add(if (isBot) LocationMessage.TYPE_BOT_MAP else LocationMessage.TYPE_USER_MAP)
|
||||
types.add(if (isBot) LocationMessage.TYPE_BOT_TEXT else LocationMessage.TYPE_USER_TEXT)
|
||||
types.add(if (isBot) LocationMessages.TYPE_BOT_MAP else LocationMessages.TYPE_USER_MAP)
|
||||
types.add(if (isBot) LocationMessages.TYPE_BOT_TEXT else LocationMessages.TYPE_USER_TEXT)
|
||||
}
|
||||
}
|
||||
chatsShareInfo.values.forEach { shareInfo ->
|
||||
if (shareInfo.pendingTdLib >= 10) {
|
||||
bufferedMessagesFull = true
|
||||
}
|
||||
types.forEach {
|
||||
val message = LocationMessage(userId, shareInfo.chatId, latitude, longitude, location.altitude, location.speed.toDouble(),
|
||||
location.accuracy.toDouble(), location.bearing.toDouble(), location.time, it, LocationMessage.STATUS_PREPARED, shareInfo.currentMapMessageId)
|
||||
app.locationMessages.addOutgoingMessage(message)
|
||||
}
|
||||
}
|
||||
}
|
||||
val message = BufferMessage(shareInfo.chatId, latitude, longitude, location.altitude, location.speed.toDouble(),
|
||||
location.accuracy.toDouble(), location.bearing.toDouble(), location.time, it, LocationMessages.STATUS_PREPARED)
|
||||
|
||||
private fun shareMessages() {
|
||||
var bufferedMessagesFull = false
|
||||
app.locationMessages.getPreparedMessages().forEach {
|
||||
val shareChatInfo = app.settings.getChatsShareInfo()[it.chatId]
|
||||
if (shareChatInfo != null) {
|
||||
bufferedMessagesFull = shareChatInfo.bufferedMessages < 10
|
||||
if (bufferedMessagesFull) {
|
||||
when {
|
||||
it.type == LocationMessage.TYPE_USER_TEXT -> {
|
||||
shareChatInfo.bufferedMessages++
|
||||
it.status = LocationMessage.STATUS_PENDING
|
||||
app.telegramHelper.sendLiveLocationText(shareChatInfo, it)
|
||||
when (app.settings.shareTypeValue) {
|
||||
SHARE_TYPE_MAP -> {
|
||||
prepareMapMessage(shareInfo, message, isBot, sharingMode)
|
||||
}
|
||||
it.type == LocationMessage.TYPE_USER_MAP -> {
|
||||
shareChatInfo.bufferedMessages++
|
||||
it.status = LocationMessage.STATUS_PENDING
|
||||
app.telegramHelper.sendLiveLocationMap(shareChatInfo, it)
|
||||
}
|
||||
it.type == LocationMessage.TYPE_BOT_TEXT -> {
|
||||
sendLocationToBot(it, app.settings.currentSharingMode, shareChatInfo, SHARE_TYPE_TEXT)
|
||||
}
|
||||
it.type == LocationMessage.TYPE_BOT_MAP -> {
|
||||
sendLocationToBot(it, app.settings.currentSharingMode, shareChatInfo, SHARE_TYPE_MAP)
|
||||
SHARE_TYPE_TEXT -> {
|
||||
prepareTextMessage(shareInfo, message, isBot, sharingMode)
|
||||
}
|
||||
SHARE_TYPE_MAP_AND_TEXT -> {
|
||||
prepareMapMessage(shareInfo, message, isBot, sharingMode)
|
||||
prepareTextMessage(shareInfo, message, isBot, sharingMode)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -193,6 +179,58 @@ class ShareLocationHelper(private val app: TelegramApplication) {
|
|||
}
|
||||
}
|
||||
|
||||
private fun prepareTextMessage(shareInfo: TelegramSettings.ShareChatInfo,message: BufferMessage,isBot:Boolean, sharingMode: String) {
|
||||
if (shareInfo.currentTextMessageId == -1L) {
|
||||
if (shareInfo.pendingTextMessage) {
|
||||
app.locationMessages.addBufferedMessage(message)
|
||||
} else {
|
||||
if (isBot) {
|
||||
sendLocationToBot(message, sharingMode, shareInfo, SHARE_TYPE_TEXT)
|
||||
} else {
|
||||
shareInfo.pendingTdLib++
|
||||
app.telegramHelper.sendNewTextLocation(shareInfo, message)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (isBot) {
|
||||
sendLocationToBot(message, sharingMode, shareInfo, SHARE_TYPE_TEXT)
|
||||
} else {
|
||||
if (shareInfo.pendingTdLib < 10) {
|
||||
shareInfo.pendingTdLib++
|
||||
app.telegramHelper.editTextLocation(shareInfo, message)
|
||||
} else {
|
||||
app.locationMessages.addBufferedMessage(message)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun prepareMapMessage(shareInfo: TelegramSettings.ShareChatInfo,message: BufferMessage,isBot:Boolean, sharingMode: String) {
|
||||
if (shareInfo.currentMapMessageId == -1L) {
|
||||
if (shareInfo.pendingMapMessage) {
|
||||
app.locationMessages.addBufferedMessage(message)
|
||||
} else {
|
||||
if (isBot) {
|
||||
sendLocationToBot(message, sharingMode, shareInfo, SHARE_TYPE_MAP)
|
||||
} else {
|
||||
shareInfo.pendingTdLib++
|
||||
app.telegramHelper.sendNewMapLocation(shareInfo, message)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (isBot) {
|
||||
sendLocationToBot(message, sharingMode, shareInfo, SHARE_TYPE_MAP)
|
||||
} else {
|
||||
if (shareInfo.pendingTdLib < 10) {
|
||||
shareInfo.pendingTdLib++
|
||||
app.telegramHelper.editMapLocation(shareInfo, message)
|
||||
} else {
|
||||
app.locationMessages.addBufferedMessage(message)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkNetworkType(){
|
||||
if (app.isInternetConnectionAvailable) {
|
||||
val networkType = when {
|
||||
|
@ -204,9 +242,9 @@ class ShareLocationHelper(private val app: TelegramApplication) {
|
|||
}
|
||||
}
|
||||
|
||||
private fun sendLocationToBot(locationMessage: LocationMessage, sharingMode: String, shareInfo: TelegramSettings.ShareChatInfo, shareType: String) {
|
||||
private fun sendLocationToBot(locationMessage: BufferMessage, sharingMode: String, shareInfo: TelegramSettings.ShareChatInfo, shareType: String) {
|
||||
if (app.isInternetConnectionAvailable) {
|
||||
locationMessage.status = LocationMessage.STATUS_PENDING
|
||||
// locationMessage.status = LocationMessage.STATUS_PENDING
|
||||
val url = getDeviceSharingUrl(locationMessage, sharingMode)
|
||||
AndroidNetworkUtils.sendRequestAsync(app, url, null, "Send Location", false, false,
|
||||
object : AndroidNetworkUtils.OnRequestResultListener {
|
||||
|
@ -216,7 +254,7 @@ class ShareLocationHelper(private val app: TelegramApplication) {
|
|||
val osmandBotId = app.telegramHelper.getOsmandBot()?.id ?: -1
|
||||
val device = app.settings.getCurrentSharingDevice()
|
||||
|
||||
locationMessage.status = if (success) LocationMessage.STATUS_SENT else LocationMessage.STATUS_ERROR
|
||||
// locationMessage.status = if (success) LocationMessage.STATUS_SENT else LocationMessage.STATUS_ERROR
|
||||
if (success && shareInfo.shouldSendViaBotMessage && osmandBotId != -1 && device != null) {
|
||||
app.telegramHelper.sendViaBotLocationMessage(osmandBotId, shareInfo, TdApi.Location(locationMessage.lat, locationMessage.lon), device, shareType)
|
||||
shareInfo.shouldSendViaBotMessage = false
|
||||
|
@ -226,7 +264,7 @@ class ShareLocationHelper(private val app: TelegramApplication) {
|
|||
}
|
||||
}
|
||||
|
||||
private fun getDeviceSharingUrl(loc: LocationMessage, sharingMode: String): String {
|
||||
private fun getDeviceSharingUrl(loc: BufferMessage, sharingMode: String): String {
|
||||
val url = "$BASE_URL/device/$sharingMode/send?lat=${loc.lat}&lon=${loc.lon}"
|
||||
val builder = StringBuilder(url)
|
||||
if (loc.bearing != 0.0) {
|
||||
|
|
|
@ -761,27 +761,6 @@ class TelegramHelper private constructor() {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @chatId Id of the chat
|
||||
* @livePeriod Period for which the location can be updated, in seconds; should be between 60 and 86400 for a live location and 0 otherwise.
|
||||
* @latitude Latitude of the location
|
||||
* @longitude Longitude of the location
|
||||
*/
|
||||
fun sendLiveLocationMessage(chatsShareInfo:Map<Long, TelegramSettings.ShareChatInfo>, latitude: Double, longitude: Double): Boolean {
|
||||
if (!requestingActiveLiveLocationMessages && haveAuthorization) {
|
||||
if (needRefreshActiveLiveLocationMessages) {
|
||||
getActiveLiveLocationMessages {
|
||||
sendLiveLocationImpl(chatsShareInfo, latitude, longitude)
|
||||
}
|
||||
needRefreshActiveLiveLocationMessages = false
|
||||
} else {
|
||||
sendLiveLocationImpl(chatsShareInfo, latitude, longitude)
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun stopSendingLiveLocationToChat(shareInfo: TelegramSettings.ShareChatInfo) {
|
||||
if (shareInfo.currentMapMessageId != -1L && shareInfo.chatId != -1L) {
|
||||
client?.send(
|
||||
|
@ -831,7 +810,7 @@ class TelegramHelper private constructor() {
|
|||
|
||||
private fun recreateLiveLocationMessage(
|
||||
shareInfo: TelegramSettings.ShareChatInfo,
|
||||
content: TdApi.InputMessageContent,locationMessage: LocationMessages.LocationMessage?
|
||||
content: TdApi.InputMessageContent,locationMessage: LocationMessages.BufferMessage?
|
||||
) {
|
||||
if (shareInfo.chatId != -1L) {
|
||||
val array = LongArray(1)
|
||||
|
@ -861,21 +840,41 @@ class TelegramHelper private constructor() {
|
|||
needRefreshActiveLiveLocationMessages = true
|
||||
}
|
||||
|
||||
private fun sendNewLiveLocationMessage(shareInfo: TelegramSettings.ShareChatInfo, content: TdApi.InputMessageContent, locationMessage: LocationMessages.LocationMessage?) {
|
||||
private fun sendNewLiveLocationMessage(shareInfo: TelegramSettings.ShareChatInfo, content: TdApi.InputMessageContent, locationMessage: LocationMessages.BufferMessage?) {
|
||||
needRefreshActiveLiveLocationMessages = true
|
||||
log.debug("sendNewLiveLocationMessage")
|
||||
client?.send(
|
||||
TdApi.SendMessage(shareInfo.chatId, 0, false, true, null, content)) { obj ->
|
||||
client?.send(TdApi.SendMessage(shareInfo.chatId, 0, false, true, null, content)) { obj ->
|
||||
if (locationMessage?.type == LocationMessages.TYPE_USER_TEXT || locationMessage?.type == LocationMessages.TYPE_BOT_TEXT) {
|
||||
handleTextLocationMessageUpdate(obj, shareInfo, locationMessage)
|
||||
} else if (locationMessage?.type == LocationMessages.TYPE_USER_MAP || locationMessage?.type == LocationMessages.TYPE_BOT_MAP) {
|
||||
handleMapLocationMessageUpdate(obj, shareInfo, locationMessage)
|
||||
}
|
||||
}
|
||||
|
||||
private fun sendLiveLocationImpl(chatsShareInfo: Map<Long, TelegramSettings.ShareChatInfo>, latitude: Double, longitude: Double) {
|
||||
val location = TdApi.Location(latitude, longitude)
|
||||
chatsShareInfo.forEach { (chatId, shareInfo) ->
|
||||
if (shareInfo.getChatLiveMessageExpireTime() <= 0) {
|
||||
return@forEach
|
||||
}
|
||||
|
||||
fun sendNewTextLocation(shareInfo: TelegramSettings.ShareChatInfo, location: LocationMessages.BufferMessage) {
|
||||
shareInfo.updateTextMessageId = 1
|
||||
val content = OsmandLocationUtils.getTextMessageContent(shareInfo.updateTextMessageId, location)
|
||||
if (!shareInfo.pendingTextMessage) {
|
||||
shareInfo.pendingTextMessage = true
|
||||
client?.send(TdApi.SendMessage(shareInfo.chatId, 0, false, true, null, content)) { obj ->
|
||||
handleTextLocationMessageUpdate(obj, shareInfo, location)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun editTextLocation(shareInfo: TelegramSettings.ShareChatInfo, location: LocationMessages.BufferMessage) {
|
||||
val content = OsmandLocationUtils.getTextMessageContent(shareInfo.updateTextMessageId, location)
|
||||
if (shareInfo.currentTextMessageId!=-1L) {
|
||||
client?.send(TdApi.EditMessageText(shareInfo.chatId, shareInfo.currentTextMessageId, null, content)) { obj ->
|
||||
handleTextLocationMessageUpdate(obj, shareInfo, location)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun sendNewMapLocation(shareInfo: TelegramSettings.ShareChatInfo, locationMessage: LocationMessages.BufferMessage) {
|
||||
needRefreshActiveLiveLocationMessages = true
|
||||
val location = TdApi.Location(locationMessage.lat, locationMessage.lon)
|
||||
val livePeriod =
|
||||
if (shareInfo.currentMessageLimit > (shareInfo.start + MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC)) {
|
||||
MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC
|
||||
|
@ -883,84 +882,26 @@ class TelegramHelper private constructor() {
|
|||
shareInfo.livePeriod.toInt()
|
||||
}
|
||||
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.shouldDeletePreviousMapMessage) {
|
||||
recreateLiveLocationMessage(shareInfo, content, null)
|
||||
shareInfo.shouldDeletePreviousMapMessage = false
|
||||
shareInfo.currentMapMessageId = -1
|
||||
} else {
|
||||
log.debug("EditMessageLiveLocation - $msgId")
|
||||
client?.send(
|
||||
TdApi.EditMessageLiveLocation(chatId, msgId, null, location)) { obj ->
|
||||
handleMapLocationMessageUpdate(obj, shareInfo, null)
|
||||
}
|
||||
}
|
||||
} else if (!shareInfo.pendingMapMessage || shareInfo.pendingMapMessage && timeAfterLastSendMessage > SEND_NEW_MESSAGE_INTERVAL_SEC) {
|
||||
sendNewLiveLocationMessage(shareInfo, content, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun sendLiveLocationMap(shareInfo: TelegramSettings.ShareChatInfo, locationMessage: LocationMessages.LocationMessage) {
|
||||
val location = TdApi.Location(locationMessage.lat, locationMessage.lon)
|
||||
val livePeriod = if (shareInfo.currentMessageLimit > (shareInfo.start + MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC)) {
|
||||
MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC
|
||||
} else {
|
||||
shareInfo.livePeriod.toInt()
|
||||
}
|
||||
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.shouldDeletePreviousMapMessage) {
|
||||
recreateLiveLocationMessage(shareInfo, content, locationMessage)
|
||||
shareInfo.shouldDeletePreviousMapMessage = false
|
||||
shareInfo.currentMapMessageId = -1
|
||||
} else {
|
||||
log.debug("EditMessageLiveLocation - $msgId")
|
||||
client?.send(
|
||||
TdApi.EditMessageLiveLocation(shareInfo.chatId, msgId, null, location)) { obj ->
|
||||
if (!shareInfo.pendingMapMessage) {
|
||||
shareInfo.pendingMapMessage = true
|
||||
client?.send(TdApi.SendMessage(shareInfo.chatId, 0, false, true, null, content)) { obj ->
|
||||
handleMapLocationMessageUpdate(obj, shareInfo, locationMessage)
|
||||
}
|
||||
}
|
||||
} else if (!shareInfo.pendingMapMessage || shareInfo.pendingMapMessage && timeAfterLastSendMessage > SEND_NEW_MESSAGE_INTERVAL_SEC) {
|
||||
sendNewLiveLocationMessage(shareInfo, content, locationMessage)
|
||||
}
|
||||
}
|
||||
|
||||
fun sendLiveLocationText(shareInfo: TelegramSettings.ShareChatInfo, location: LocationMessages.LocationMessage) {
|
||||
val msgId = shareInfo.currentTextMessageId
|
||||
if (msgId == -1L) {
|
||||
shareInfo.updateTextMessageId = 1
|
||||
}
|
||||
val content = OsmandLocationUtils.getTextMessageContent(shareInfo.updateTextMessageId, location)
|
||||
val timeAfterLastSendMessage = ((System.currentTimeMillis() / 1000) - shareInfo.lastSendTextMessageTime)
|
||||
log.debug("sendLiveLocationText - $msgId pendingMapMessage ${shareInfo.pendingTextMessage}")
|
||||
if (msgId != -1L) {
|
||||
if (shareInfo.shouldDeletePreviousTextMessage) {
|
||||
recreateLiveLocationMessage(shareInfo, content, location)
|
||||
shareInfo.shouldDeletePreviousTextMessage = false
|
||||
} else {
|
||||
client?.send(TdApi.EditMessageText(shareInfo.chatId, msgId, null, content)) { obj ->
|
||||
handleTextLocationMessageUpdate(obj, shareInfo, location)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!shareInfo.pendingTextMessage) {
|
||||
client?.send(TdApi.SendMessage(shareInfo.chatId, 0, false, false, null, content)) { obj ->
|
||||
handleTextLocationMessageUpdate(obj, shareInfo, location)
|
||||
}
|
||||
} else if(timeAfterLastSendMessage > SEND_NEW_MESSAGE_INTERVAL_SEC){
|
||||
|
||||
fun editMapLocation(shareInfo: TelegramSettings.ShareChatInfo, locationMessage: LocationMessages.BufferMessage) {
|
||||
needRefreshActiveLiveLocationMessages = true
|
||||
val location = TdApi.Location(locationMessage.lat, locationMessage.lon)
|
||||
if (shareInfo.currentMapMessageId!=-1L) {
|
||||
client?.send(
|
||||
TdApi.EditMessageLiveLocation(shareInfo.chatId, shareInfo.currentMapMessageId, null, location)) { obj ->
|
||||
handleMapLocationMessageUpdate(obj, shareInfo, locationMessage)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleMapLocationMessageUpdate(obj: TdApi.Object, shareInfo: TelegramSettings.ShareChatInfo, location: LocationMessages.LocationMessage?) {
|
||||
private fun handleMapLocationMessageUpdate(obj: TdApi.Object, shareInfo: TelegramSettings.ShareChatInfo, location: LocationMessages.BufferMessage?) {
|
||||
when (obj.constructor) {
|
||||
TdApi.Error.CONSTRUCTOR -> {
|
||||
val error = obj as TdApi.Error
|
||||
|
@ -980,7 +921,8 @@ class TelegramHelper private constructor() {
|
|||
obj.sendingState?.constructor == TdApi.MessageSendingStateFailed.CONSTRUCTOR -> {
|
||||
shareInfo.hasSharingError = true
|
||||
needRefreshActiveLiveLocationMessages = true
|
||||
location?.status = LocationMessages.LocationMessage.STATUS_ERROR
|
||||
shareInfo.pendingMapMessage = false
|
||||
// location?.status = LocationMessages.LocationMessage.STATUS_ERROR
|
||||
outgoingMessagesListeners.forEach {
|
||||
it.onSendLiveLocationError(-1, "Map location message ${obj.id} failed to send")
|
||||
}
|
||||
|
@ -988,14 +930,15 @@ class TelegramHelper private constructor() {
|
|||
obj.sendingState?.constructor == TdApi.MessageSendingStatePending.CONSTRUCTOR -> {
|
||||
shareInfo.pendingMapMessage = true
|
||||
shareInfo.lastSendMapMessageTime = obj.date
|
||||
location?.status = LocationMessages.LocationMessage.STATUS_PENDING
|
||||
// location?.status = LocationMessages.LocationMessage.STATUS_PENDING
|
||||
log.debug("handleMapLocationMessageUpdate - MessageSendingStatePending")
|
||||
}
|
||||
else -> {
|
||||
shareInfo.hasSharingError = false
|
||||
shareInfo.bufferedMessages--
|
||||
location?.messageId = obj.id
|
||||
location?.status = LocationMessages.LocationMessage.STATUS_SENT
|
||||
shareInfo.pendingTdLib--
|
||||
shareInfo.pendingMapMessage = false
|
||||
// location?.messageId = obj.id
|
||||
// location?.status = LocationMessages.LocationMessage.STATUS_SENT
|
||||
outgoingMessagesListeners.forEach {
|
||||
it.onUpdateMessages(listOf(obj))
|
||||
}
|
||||
|
@ -1006,7 +949,7 @@ class TelegramHelper private constructor() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun handleTextLocationMessageUpdate(obj: TdApi.Object, shareInfo: TelegramSettings.ShareChatInfo, location: LocationMessages.LocationMessage?) {
|
||||
private fun handleTextLocationMessageUpdate(obj: TdApi.Object, shareInfo: TelegramSettings.ShareChatInfo, location: LocationMessages.BufferMessage?) {
|
||||
when (obj.constructor) {
|
||||
TdApi.Error.CONSTRUCTOR -> {
|
||||
val error = obj as TdApi.Error
|
||||
|
@ -1024,9 +967,10 @@ class TelegramHelper private constructor() {
|
|||
when {
|
||||
obj.sendingState?.constructor == TdApi.MessageSendingStateFailed.CONSTRUCTOR -> {
|
||||
shareInfo.hasSharingError = true
|
||||
shareInfo.bufferedMessages--
|
||||
shareInfo.pendingTdLib--
|
||||
shareInfo.pendingTextMessage = false
|
||||
needRefreshActiveLiveLocationMessages = true
|
||||
location?.status = LocationMessages.LocationMessage.STATUS_ERROR
|
||||
// location?.status = LocationMessages.LocationMessage.STATUS_ERROR
|
||||
outgoingMessagesListeners.forEach {
|
||||
it.onSendLiveLocationError(-1, "Text location message ${obj.id} failed to send")
|
||||
}
|
||||
|
@ -1034,14 +978,15 @@ class TelegramHelper private constructor() {
|
|||
obj.sendingState?.constructor == TdApi.MessageSendingStatePending.CONSTRUCTOR -> {
|
||||
shareInfo.pendingTextMessage = true
|
||||
shareInfo.lastSendTextMessageTime = obj.date
|
||||
location?.status = LocationMessages.LocationMessage.STATUS_PENDING
|
||||
// location?.status = LocationMessages.LocationMessage.STATUS_PENDING
|
||||
log.debug("handleTextLocationMessageUpdate - MessageSendingStatePending")
|
||||
}
|
||||
else -> {
|
||||
shareInfo.hasSharingError = false
|
||||
shareInfo.bufferedMessages--
|
||||
location?.messageId = obj.id
|
||||
location?.status = LocationMessages.LocationMessage.STATUS_SENT
|
||||
shareInfo.pendingTdLib--
|
||||
shareInfo.pendingTextMessage = false
|
||||
// location?.messageId = obj.id
|
||||
// location?.status = LocationMessages.LocationMessage.STATUS_SENT
|
||||
outgoingMessagesListeners.forEach {
|
||||
it.onUpdateMessages(listOf(obj))
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import android.widget.*
|
|||
import net.osmand.PlatformUtil
|
||||
import net.osmand.telegram.R
|
||||
import net.osmand.telegram.TelegramApplication
|
||||
import net.osmand.telegram.helpers.LocationMessages
|
||||
import net.osmand.telegram.helpers.LocationMessages.LocationMessage
|
||||
import net.osmand.telegram.helpers.OsmandAidlHelper
|
||||
import net.osmand.telegram.helpers.TelegramHelper
|
||||
|
@ -293,7 +294,7 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene
|
|||
}
|
||||
if (app.telegramService == null) {
|
||||
messages.forEach {
|
||||
val locationMessage = OsmandLocationUtils.parseMessage(it, telegramHelper, LocationMessage.STATUS_PREPARED)
|
||||
val locationMessage = OsmandLocationUtils.parseMessage(it, telegramHelper, LocationMessages.STATUS_PREPARED)
|
||||
if (locationMessage != null) {
|
||||
app.locationMessages.addIngoingMessage(locationMessage)
|
||||
}
|
||||
|
@ -349,8 +350,7 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene
|
|||
fun logoutTelegram(silent: Boolean = false) {
|
||||
if (telegramHelper.getTelegramAuthorizationState() == TelegramHelper.TelegramAuthorizationState.READY) {
|
||||
if (app.isInternetConnectionAvailable) {
|
||||
// todo - why delete messages on logout?
|
||||
app.locationMessages.clearOutgoingMessages()
|
||||
app.locationMessages.clearBufferedMessages()
|
||||
settings.clear()
|
||||
telegramHelper.logout()
|
||||
} else {
|
||||
|
|
|
@ -190,22 +190,22 @@ class TimelineTabFragment : Fragment() {
|
|||
val res = mutableListOf<ListItem>()
|
||||
val ignoredUsersIds = ArrayList<Int>()
|
||||
val currentUserId = telegramHelper.getCurrentUser()?.id
|
||||
if (currentUserId != null) {
|
||||
val locationMessages = app.locationMessages.collectRecordedDataForUser(currentUserId, 0, start, end)
|
||||
// todo - why do we need convert to gpx on update? Is locationMessages not enough to display info?
|
||||
OsmandLocationUtils.convertLocationMessagesToGpxFiles(locationMessages, false).forEach {
|
||||
TelegramUiHelper.gpxToChatItem(telegramHelper, it, true)?.also { chatItem ->
|
||||
res.add(chatItem)
|
||||
}
|
||||
}
|
||||
ignoredUsersIds.add(currentUserId)
|
||||
}
|
||||
val locationMessages = app.locationMessages.collectRecordedDataForUsers(start, end, ignoredUsersIds)
|
||||
OsmandLocationUtils.convertLocationMessagesToGpxFiles(locationMessages).forEach {
|
||||
TelegramUiHelper.gpxToChatItem(telegramHelper, it,false)?.also { chatItem ->
|
||||
res.add(chatItem)
|
||||
}
|
||||
}
|
||||
// if (currentUserId != null) {
|
||||
// val locationMessages = app.locationMessages.collectRecordedDataForUser(currentUserId, 0, start, end)
|
||||
// // todo - why do we need convert to gpx on update? Is locationMessages not enough to display info?
|
||||
// OsmandLocationUtils.convertLocationMessagesToGpxFiles(locationMessages, false).forEach {
|
||||
// TelegramUiHelper.gpxToChatItem(telegramHelper, it, true)?.also { chatItem ->
|
||||
// res.add(chatItem)
|
||||
// }
|
||||
// }
|
||||
// ignoredUsersIds.add(currentUserId)
|
||||
// }
|
||||
// val locationMessages = app.locationMessages.collectRecordedDataForUsers(start, end, ignoredUsersIds)
|
||||
// OsmandLocationUtils.convertLocationMessagesToGpxFiles(locationMessages).forEach {
|
||||
// TelegramUiHelper.gpxToChatItem(telegramHelper, it,false)?.also { chatItem ->
|
||||
// res.add(chatItem)
|
||||
// }
|
||||
// }
|
||||
|
||||
adapter.items = sortAdapterItems(res)
|
||||
}
|
||||
|
|
|
@ -207,14 +207,14 @@ class UserGpxInfoFragment : BaseDialogFragment() {
|
|||
}
|
||||
|
||||
private fun updateGpxInfo() {
|
||||
gpxFile = OsmandLocationUtils.convertLocationMessagesToGpxFiles(
|
||||
app.locationMessages.collectRecordedDataForUser(
|
||||
gpxFile.userId,
|
||||
gpxFile.chatId,
|
||||
startCalendar.timeInMillis,
|
||||
endCalendar.timeInMillis
|
||||
)
|
||||
).first()
|
||||
// gpxFile = OsmandLocationUtils.convertLocationMessagesToGpxFiles(
|
||||
// app.locationMessages.collectRecordedDataForUser(
|
||||
// gpxFile.userId,
|
||||
// gpxFile.chatId,
|
||||
// startCalendar.timeInMillis,
|
||||
// endCalendar.timeInMillis
|
||||
// )
|
||||
// ).first()
|
||||
updateGPXStatisticRow()
|
||||
updateDateAndTimeButtons()
|
||||
updateGPXMap()
|
||||
|
|
|
@ -3,7 +3,9 @@ package net.osmand.telegram.utils
|
|||
import android.os.AsyncTask
|
||||
import net.osmand.Location
|
||||
import net.osmand.telegram.TelegramApplication
|
||||
import net.osmand.telegram.helpers.LocationMessages
|
||||
import net.osmand.telegram.helpers.LocationMessages.LocationMessage
|
||||
import net.osmand.telegram.helpers.LocationMessages.BufferMessage
|
||||
import net.osmand.telegram.helpers.TelegramHelper
|
||||
import net.osmand.telegram.helpers.TelegramUiHelper
|
||||
import net.osmand.util.GeoPointParserUtil
|
||||
|
@ -108,7 +110,7 @@ object OsmandLocationUtils {
|
|||
if (parsedMessageContent != null) {
|
||||
locationMessage = LocationMessage(helper.getSenderMessageId(message), message.chatId, parsedMessageContent.lat,
|
||||
parsedMessageContent.lon, parsedMessageContent.altitude, parsedMessageContent.speed, parsedMessageContent.hdop,
|
||||
parsedMessageContent.bearing, parsedMessageContent.lastUpdated * 1000L, messageType, status, message.id)
|
||||
parsedMessageContent.bearing, parsedMessageContent.lastUpdated * 1000L, messageType)
|
||||
}
|
||||
return locationMessage
|
||||
}
|
||||
|
@ -121,6 +123,10 @@ object OsmandLocationUtils {
|
|||
return String.format(Locale.US, "%.5f, %.5f", sig.lat, sig.lon)
|
||||
}
|
||||
|
||||
fun formatLocation(sig: BufferMessage): String {
|
||||
return String.format(Locale.US, "%.5f, %.5f", sig.lat, sig.lon)
|
||||
}
|
||||
|
||||
fun formatFullTime(ti: Long): String {
|
||||
val dt = Date(ti)
|
||||
return UTC_DATE_FORMAT.format(dt) + " " + UTC_TIME_FORMAT.format(dt) + " UTC"
|
||||
|
@ -313,6 +319,45 @@ object OsmandLocationUtils {
|
|||
return TdApi.InputMessageText(TdApi.FormattedText(textMessage, entities.toTypedArray()), true, true)
|
||||
}
|
||||
|
||||
fun getTextMessageContent(updateId: Int, location: BufferMessage): TdApi.InputMessageText {
|
||||
val entities = mutableListOf<TdApi.TextEntity>()
|
||||
val builder = StringBuilder()
|
||||
val locationMessage = formatLocation(location)
|
||||
|
||||
val firstSpace = USER_TEXT_LOCATION_TITLE.indexOf(' ')
|
||||
val secondSpace = USER_TEXT_LOCATION_TITLE.indexOf(' ', firstSpace + 1)
|
||||
entities.add(TdApi.TextEntity(builder.length + firstSpace + 1, secondSpace - firstSpace, TdApi.TextEntityTypeTextUrl(SHARING_LINK)))
|
||||
builder.append("$USER_TEXT_LOCATION_TITLE\n")
|
||||
|
||||
entities.add(TdApi.TextEntity(builder.lastIndex, LOCATION_PREFIX.length, TdApi.TextEntityTypeBold()))
|
||||
builder.append(LOCATION_PREFIX)
|
||||
|
||||
entities.add(TdApi.TextEntity(builder.length, locationMessage.length,
|
||||
TdApi.TextEntityTypeTextUrl("$BASE_SHARING_URL?lat=${location.lat}&lon=${location.lon}")))
|
||||
builder.append("$locationMessage\n")
|
||||
|
||||
if (location.altitude != 0.0) {
|
||||
entities.add(TdApi.TextEntity(builder.lastIndex, ALTITUDE_PREFIX.length, TdApi.TextEntityTypeBold()))
|
||||
builder.append(String.format(Locale.US, "$ALTITUDE_PREFIX%.1f m\n", location.altitude))
|
||||
}
|
||||
if (location.speed > 0) {
|
||||
entities.add(TdApi.TextEntity(builder.lastIndex, SPEED_PREFIX.length, TdApi.TextEntityTypeBold()))
|
||||
builder.append(String.format(Locale.US, "$SPEED_PREFIX%.1f m/s\n", location.speed))
|
||||
}
|
||||
if (location.hdop != 0.0 && location.speed == 0.0) {
|
||||
entities.add(TdApi.TextEntity(builder.lastIndex, HDOP_PREFIX.length, TdApi.TextEntityTypeBold()))
|
||||
builder.append(String.format(Locale.US, "$HDOP_PREFIX%d m\n", location.hdop.toInt()))
|
||||
}
|
||||
if (updateId == 0) {
|
||||
builder.append(String.format("$UPDATED_PREFIX%s\n", formatFullTime(location.date)))
|
||||
} else {
|
||||
builder.append(String.format("$UPDATED_PREFIX%s (%d)\n", formatFullTime(location.date), updateId))
|
||||
}
|
||||
val textMessage = builder.toString().trim()
|
||||
|
||||
return TdApi.InputMessageText(TdApi.FormattedText(textMessage, entities.toTypedArray()), true, true)
|
||||
}
|
||||
|
||||
fun convertLocationMessagesToGpxFiles(items: List<LocationMessage>, newGpxPerChat: Boolean = true): List<GPXUtilities.GPXFile> {
|
||||
val dataTracks = ArrayList<GPXUtilities.GPXFile>()
|
||||
|
||||
|
|
Loading…
Reference in a new issue