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.util.Log
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import net.osmand.PlatformUtil
|
import net.osmand.PlatformUtil
|
||||||
|
import net.osmand.telegram.helpers.LocationMessages
|
||||||
import net.osmand.telegram.helpers.LocationMessages.LocationMessage
|
import net.osmand.telegram.helpers.LocationMessages.LocationMessage
|
||||||
import net.osmand.telegram.helpers.TelegramHelper.TelegramIncomingMessagesListener
|
import net.osmand.telegram.helpers.TelegramHelper.TelegramIncomingMessagesListener
|
||||||
import net.osmand.telegram.helpers.TelegramHelper.TelegramOutgoingMessagesListener
|
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) {
|
override fun onReceiveChatLocationMessages(chatId: Long, vararg messages: TdApi.Message) {
|
||||||
app().showLocationHelper.startShowMessagesTask(chatId, *messages)
|
app().showLocationHelper.startShowMessagesTask(chatId, *messages)
|
||||||
messages.forEach {
|
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) {
|
if (locationMessage != null) {
|
||||||
app().locationMessages.addIngoingMessage(locationMessage)
|
app().locationMessages.addIngoingMessage(locationMessage)
|
||||||
}
|
}
|
||||||
|
|
|
@ -845,13 +845,15 @@ class TelegramSettings(private val app: TelegramApplication) {
|
||||||
var updateTextMessageId = 1
|
var updateTextMessageId = 1
|
||||||
var currentMessageLimit = -1L
|
var currentMessageLimit = -1L
|
||||||
var currentMapMessageId = -1L
|
var currentMapMessageId = -1L
|
||||||
|
var oldMapMessageId = -1L
|
||||||
var currentTextMessageId = -1L
|
var currentTextMessageId = -1L
|
||||||
|
var oldTextMessageId = -1L
|
||||||
var userSetLivePeriod = -1L
|
var userSetLivePeriod = -1L
|
||||||
var userSetLivePeriodStart = -1L
|
var userSetLivePeriodStart = -1L
|
||||||
var lastSuccessfulSendTimeMs = -1L
|
var lastSuccessfulSendTimeMs = -1L
|
||||||
var lastSendTextMessageTime = -1
|
var lastSendTextMessageTime = -1
|
||||||
var lastSendMapMessageTime = -1
|
var lastSendMapMessageTime = -1
|
||||||
var bufferedMessages = 0
|
var pendingTdLib = 0
|
||||||
var pendingTextMessage = false
|
var pendingTextMessage = false
|
||||||
var pendingMapMessage = false
|
var pendingMapMessage = false
|
||||||
var shouldSendViaBotMessage = false
|
var shouldSendViaBotMessage = false
|
||||||
|
|
|
@ -11,7 +11,7 @@ import kotlin.collections.ArrayList
|
||||||
class LocationMessages(val app: TelegramApplication) {
|
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.
|
// 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
|
private val dbHelper: SQLiteHelper
|
||||||
|
|
||||||
|
@ -20,27 +20,23 @@ class LocationMessages(val app: TelegramApplication) {
|
||||||
readBufferedMessages()
|
readBufferedMessages()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getPreparedMessages(): List<LocationMessage> {
|
fun getPreparedMessages(): List<BufferMessage> {
|
||||||
val currentUserId = app.telegramHelper.getCurrentUserId()
|
return bufferedMessages.sortedBy { it.date }
|
||||||
return bufferedMessages.filter { it.userId == currentUserId && it.status == LocationMessage.STATUS_PREPARED }.sortedBy { it.date }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo - drop method. add collected / sent messages count to ShareChatInfo
|
// // todo - drop method. add collected / sent messages count to ShareChatInfo
|
||||||
fun getOutgoingMessages(chatId: Long): List<LocationMessage> {
|
// fun getOutgoingMessages(chatId: Long): List<LocationMessage> {
|
||||||
val currentUserId = app.telegramHelper.getCurrentUserId()
|
// val currentUserId = app.telegramHelper.getCurrentUserId()
|
||||||
return bufferedMessages.filter { it.userId == currentUserId && it.chatId == chatId }.sortedBy { it.date }
|
// return bufferedMessages.filter { it.userId == currentUserId && it.chatId == chatId }.sortedBy { it.date }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// todo - drop it or read from db
|
fun updateBufferedMessageStatus(oldMessage: BufferMessage, status: Int){
|
||||||
fun getSentMessages(chatId: Long, date:Long): List<LocationMessage> {
|
val messages = mutableListOf(*this.bufferedMessages.toTypedArray())
|
||||||
val currentUserId = app.telegramHelper.getCurrentUserId()
|
messages.remove(oldMessage)
|
||||||
return bufferedMessages.filter { it.userId == currentUserId && it.chatId == chatId && it.date > date }.sortedBy { it.date }
|
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
|
||||||
// todo - drop it or read from db
|
// dbHelper.addBufferedMessage(newMessage)
|
||||||
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 }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo - read from db by date (Victor's suggestion - filter by one day only. Need to be changed in UI also.
|
// 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()
|
return emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addOutgoingMessage(message: LocationMessage) {
|
fun addBufferedMessage(message: BufferMessage) {
|
||||||
val messages = mutableListOf(*this.bufferedMessages.toTypedArray())
|
val messages = mutableListOf(*this.bufferedMessages.toTypedArray())
|
||||||
messages.add(message)
|
messages.add(message)
|
||||||
this.bufferedMessages = messages
|
this.bufferedMessages = messages
|
||||||
dbHelper.addOutgoingMessage(message)
|
dbHelper.addBufferedMessage(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addIngoingMessage(message: LocationMessage) {
|
fun addIngoingMessage(message: LocationMessage) {
|
||||||
dbHelper.addIngoingMessage(message)
|
dbHelper.addIngoingMessage(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun clearOutgoingMessages() {
|
fun clearBufferedMessages() {
|
||||||
dbHelper.clearOutgoingMessages()
|
dbHelper.clearBufferedMessages()
|
||||||
bufferedMessages = emptyList()
|
bufferedMessages = emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo - both methods should be refactored since we have two tables now for outgoing/ingoing messages. Data should be read from db.
|
// 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> {
|
// fun collectRecordedDataForUser(userId: Int, chatId: Long, start: Long, end: Long): List<LocationMessage> {
|
||||||
return if (chatId == 0L) {
|
// return if (chatId == 0L) {
|
||||||
bufferedMessages.sortedWith(compareBy({ it.userId }, { it.chatId })).filter { it.userId == userId && it.date in (start + 1)..(end - 1) }
|
// bufferedMessages.sortedWith(compareBy({ it.userId }, { it.chatId })).filter { it.userId == userId && it.date in (start + 1)..(end - 1) }
|
||||||
} else {
|
// } else {
|
||||||
bufferedMessages.sortedWith(compareBy({ it.userId }, { it.chatId })).filter {
|
// 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) }
|
// it.chatId == chatId && it.userId == userId&&it.date in (start + 1)..(end - 1) }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
fun collectRecordedDataForUsers(start: Long, end: Long, ignoredUsersIds: ArrayList<Int>): List<LocationMessage> {
|
// fun collectRecordedDataForUsers(start: Long, end: Long, ignoredUsersIds: ArrayList<Int>): List<LocationMessage> {
|
||||||
return bufferedMessages.sortedWith(compareBy({ it.userId }, { it.chatId })).filter {
|
// return bufferedMessages.sortedWith(compareBy({ it.userId }, { it.chatId })).filter {
|
||||||
it.date in (start + 1)..(end - 1) && !ignoredUsersIds.contains(it.userId)
|
// it.date in (start + 1)..(end - 1) && !ignoredUsersIds.contains(it.userId)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
private fun readBufferedMessages() {
|
private fun readBufferedMessages() {
|
||||||
this.bufferedMessages = dbHelper.getOutgoingMessages();
|
this.bufferedMessages = dbHelper.getBufferedMessages()
|
||||||
}
|
}
|
||||||
|
|
||||||
private class SQLiteHelper(context: Context) :
|
private class SQLiteHelper(context: Context) :
|
||||||
SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) {
|
SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) {
|
||||||
|
|
||||||
override fun onCreate(db: SQLiteDatabase) {
|
override fun onCreate(db: SQLiteDatabase) {
|
||||||
db.execSQL(OUTGOING_TABLE_CREATE)
|
db.execSQL(TIMELINE_TABLE_CREATE)
|
||||||
db.execSQL("CREATE INDEX $DATE_INDEX ON $OUTGOING_TABLE_NAME (\"$COL_DATE\" DESC);")
|
db.execSQL("CREATE INDEX $DATE_INDEX ON $TIMELINE_TABLE_NAME (\"$COL_TIME\" DESC);")
|
||||||
db.execSQL(INGOING_TABLE_CREATE)
|
db.execSQL(BUFFER_TABLE_CREATE)
|
||||||
db.execSQL("CREATE INDEX $DATE_INDEX ON $INGOING_TABLE_NAME (\"$COL_DATE\" DESC);")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
|
override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
|
||||||
db.execSQL(OUTGOING_TABLE_DELETE)
|
db.execSQL(TIMELINE_TABLE_DELETE)
|
||||||
db.execSQL(INGOING_TABLE_DELETE)
|
db.execSQL(BUFFER_TABLE_DELETE)
|
||||||
onCreate(db)
|
onCreate(db)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun addOutgoingMessage(message: LocationMessage) {
|
internal fun addBufferedMessage(message: BufferMessage) {
|
||||||
writableDatabase?.execSQL(OUTGOING_TABLE_INSERT,
|
writableDatabase?.execSQL(BUFFER_TABLE_INSERT,
|
||||||
arrayOf(message.userId, message.chatId, message.lat, message.lon, message.altitude, message.speed,
|
arrayOf(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 addIngoingMessage(message: LocationMessage) {
|
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,
|
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> {
|
internal fun getOutgoingMessages(): List<LocationMessage> {
|
||||||
val res = arrayListOf<LocationMessage>()
|
val res = arrayListOf<LocationMessage>()
|
||||||
readableDatabase?.rawQuery(OUTGOING_TABLE_SELECT, null)?.apply {
|
readableDatabase?.rawQuery(TIMELINE_TABLE_SELECT, null)?.apply {
|
||||||
if (moveToFirst()) {
|
if (moveToFirst()) {
|
||||||
do {
|
do {
|
||||||
res.add(readLocationMessage(this@apply))
|
res.add(readLocationMessage(this@apply))
|
||||||
|
@ -125,6 +126,19 @@ class LocationMessages(val app: TelegramApplication) {
|
||||||
return res
|
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 {
|
internal fun readLocationMessage(cursor: Cursor): LocationMessage {
|
||||||
val userId = cursor.getInt(0)
|
val userId = cursor.getInt(0)
|
||||||
val chatId = cursor.getLong(1)
|
val chatId = cursor.getLong(1)
|
||||||
|
@ -136,27 +150,40 @@ class LocationMessages(val app: TelegramApplication) {
|
||||||
val bearing = cursor.getDouble(7)
|
val bearing = cursor.getDouble(7)
|
||||||
val date = cursor.getLong(8)
|
val date = cursor.getLong(8)
|
||||||
val type = cursor.getInt(9)
|
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() {
|
internal fun readBufferMessage(cursor: Cursor): BufferMessage {
|
||||||
writableDatabase?.execSQL(OUTGOING_TABLE_CLEAR)
|
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 {
|
companion object {
|
||||||
|
|
||||||
private const val DATABASE_NAME = "location_messages"
|
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 TIMELINE_TABLE_NAME = "timeline"
|
||||||
private const val INGOING_TABLE_NAME = "ingoing"
|
private const val BUFFER_TABLE_NAME = "buffer"
|
||||||
|
|
||||||
private const val COL_USER_ID = "user_id"
|
private const val COL_USER_ID = "user_id"
|
||||||
private const val COL_CHAT_ID = "chat_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_LAT = "lat"
|
||||||
private const val COL_LON = "lon"
|
private const val COL_LON = "lon"
|
||||||
private const val COL_ALTITUDE = "altitude"
|
private const val COL_ALTITUDE = "altitude"
|
||||||
|
@ -169,38 +196,49 @@ class LocationMessages(val app: TelegramApplication) {
|
||||||
|
|
||||||
private const val DATE_INDEX = "date_index"
|
private const val DATE_INDEX = "date_index"
|
||||||
|
|
||||||
// Outgoing messages table
|
// Timeline messages table
|
||||||
private const val OUTGOING_TABLE_INSERT =
|
private const val TIMELINE_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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
|
("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 =
|
private const val TIMELINE_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 )")
|
("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 =
|
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_DATE, $COL_TYPE, $COL_MESSAGE_STATUS, $COL_MESSAGE_ID FROM $OUTGOING_TABLE_NAME"
|
"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
|
// Buffer messages table
|
||||||
private const val INGOING_TABLE_INSERT =
|
private const val BUFFER_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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
|
("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 =
|
private const val BUFFER_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 )")
|
("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 =
|
private const val BUFFER_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"
|
"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(
|
data class LocationMessage(
|
||||||
val userId: Int,
|
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 chatId: Long,
|
||||||
val lat: Double,
|
val lat: Double,
|
||||||
val lon: Double,
|
val lon: Double,
|
||||||
|
@ -211,20 +249,18 @@ class LocationMessages(val app: TelegramApplication) {
|
||||||
val date: Long,
|
val date: Long,
|
||||||
val type: Int,
|
val type: Int,
|
||||||
// todo - status and messageId should be updated in db right away. Make them val instead of var.
|
// todo - status and messageId should be updated in db right away. Make them val instead of var.
|
||||||
var status: Int,
|
val status: Int)
|
||||||
var messageId: Long) {
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
const val STATUS_PREPARED = 0
|
const val STATUS_PREPARED = 0
|
||||||
const val STATUS_PENDING = 1
|
const val STATUS_PENDING = 1
|
||||||
const val STATUS_SENT = 2
|
const val STATUS_SENT = 2
|
||||||
const val STATUS_ERROR = 3
|
const val STATUS_ERROR = 3
|
||||||
|
|
||||||
const val TYPE_USER_MAP = 0
|
const val TYPE_USER_MAP = 0
|
||||||
const val TYPE_USER_TEXT = 1
|
const val TYPE_USER_TEXT = 1
|
||||||
const val TYPE_BOT_MAP = 2
|
const val TYPE_BOT_MAP = 2
|
||||||
const val TYPE_BOT_TEXT = 3
|
const val TYPE_BOT_TEXT = 3
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,7 +3,7 @@ package net.osmand.telegram.helpers
|
||||||
import net.osmand.Location
|
import net.osmand.Location
|
||||||
import net.osmand.PlatformUtil
|
import net.osmand.PlatformUtil
|
||||||
import net.osmand.telegram.*
|
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.notifications.TelegramNotification.NotificationType
|
||||||
import net.osmand.telegram.utils.AndroidNetworkUtils
|
import net.osmand.telegram.utils.AndroidNetworkUtils
|
||||||
import net.osmand.telegram.utils.BASE_URL
|
import net.osmand.telegram.utils.BASE_URL
|
||||||
|
@ -50,8 +50,7 @@ class ShareLocationHelper(private val app: TelegramApplication) {
|
||||||
|
|
||||||
if (location != null) {
|
if (location != null) {
|
||||||
if (app.settings.getChatsShareInfo().isNotEmpty()) {
|
if (app.settings.getChatsShareInfo().isNotEmpty()) {
|
||||||
addNewLocationMessages(location, app.telegramHelper.getCurrentUserId())
|
shareLocationMessages(location, app.telegramHelper.getCurrentUserId())
|
||||||
shareMessages()
|
|
||||||
}
|
}
|
||||||
lastLocationMessageSentTime = System.currentTimeMillis()
|
lastLocationMessageSentTime = System.currentTimeMillis()
|
||||||
}
|
}
|
||||||
|
@ -132,58 +131,45 @@ class ShareLocationHelper(private val app: TelegramApplication) {
|
||||||
refreshNotification()
|
refreshNotification()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addNewLocationMessages(location: Location, userId: Int) {
|
private fun shareLocationMessages(location: Location, userId: Int) {
|
||||||
val chatsShareInfo = app.settings.getChatsShareInfo()
|
val chatsShareInfo = app.settings.getChatsShareInfo()
|
||||||
val latitude = location.latitude
|
val latitude = location.latitude
|
||||||
val longitude = location.longitude
|
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>()
|
val types = mutableListOf<Int>()
|
||||||
|
var bufferedMessagesFull = false
|
||||||
|
|
||||||
when (app.settings.shareTypeValue) {
|
when (app.settings.shareTypeValue) {
|
||||||
SHARE_TYPE_MAP -> {
|
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 -> {
|
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 -> {
|
SHARE_TYPE_MAP_AND_TEXT -> {
|
||||||
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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
chatsShareInfo.values.forEach { shareInfo ->
|
chatsShareInfo.values.forEach { shareInfo ->
|
||||||
types.forEach {
|
if (shareInfo.pendingTdLib >= 10) {
|
||||||
val message = LocationMessage(userId, shareInfo.chatId, latitude, longitude, location.altitude, location.speed.toDouble(),
|
bufferedMessagesFull = true
|
||||||
location.accuracy.toDouble(), location.bearing.toDouble(), location.time, it, LocationMessage.STATUS_PREPARED, shareInfo.currentMapMessageId)
|
|
||||||
app.locationMessages.addOutgoingMessage(message)
|
|
||||||
}
|
}
|
||||||
}
|
types.forEach {
|
||||||
}
|
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() {
|
when (app.settings.shareTypeValue) {
|
||||||
var bufferedMessagesFull = false
|
SHARE_TYPE_MAP -> {
|
||||||
app.locationMessages.getPreparedMessages().forEach {
|
prepareMapMessage(shareInfo, message, isBot, sharingMode)
|
||||||
val shareChatInfo = app.settings.getChatsShareInfo()[it.chatId]
|
}
|
||||||
if (shareChatInfo != null) {
|
SHARE_TYPE_TEXT -> {
|
||||||
bufferedMessagesFull = shareChatInfo.bufferedMessages < 10
|
prepareTextMessage(shareInfo, message, isBot, sharingMode)
|
||||||
if (bufferedMessagesFull) {
|
}
|
||||||
when {
|
SHARE_TYPE_MAP_AND_TEXT -> {
|
||||||
it.type == LocationMessage.TYPE_USER_TEXT -> {
|
prepareMapMessage(shareInfo, message, isBot, sharingMode)
|
||||||
shareChatInfo.bufferedMessages++
|
prepareTextMessage(shareInfo, message, isBot, sharingMode)
|
||||||
it.status = LocationMessage.STATUS_PENDING
|
|
||||||
app.telegramHelper.sendLiveLocationText(shareChatInfo, it)
|
|
||||||
}
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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(){
|
private fun checkNetworkType(){
|
||||||
if (app.isInternetConnectionAvailable) {
|
if (app.isInternetConnectionAvailable) {
|
||||||
val networkType = when {
|
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) {
|
if (app.isInternetConnectionAvailable) {
|
||||||
locationMessage.status = LocationMessage.STATUS_PENDING
|
// locationMessage.status = LocationMessage.STATUS_PENDING
|
||||||
val url = getDeviceSharingUrl(locationMessage, sharingMode)
|
val url = getDeviceSharingUrl(locationMessage, sharingMode)
|
||||||
AndroidNetworkUtils.sendRequestAsync(app, url, null, "Send Location", false, false,
|
AndroidNetworkUtils.sendRequestAsync(app, url, null, "Send Location", false, false,
|
||||||
object : AndroidNetworkUtils.OnRequestResultListener {
|
object : AndroidNetworkUtils.OnRequestResultListener {
|
||||||
|
@ -216,7 +254,7 @@ class ShareLocationHelper(private val app: TelegramApplication) {
|
||||||
val osmandBotId = app.telegramHelper.getOsmandBot()?.id ?: -1
|
val osmandBotId = app.telegramHelper.getOsmandBot()?.id ?: -1
|
||||||
val device = app.settings.getCurrentSharingDevice()
|
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) {
|
if (success && shareInfo.shouldSendViaBotMessage && osmandBotId != -1 && device != null) {
|
||||||
app.telegramHelper.sendViaBotLocationMessage(osmandBotId, shareInfo, TdApi.Location(locationMessage.lat, locationMessage.lon), device, shareType)
|
app.telegramHelper.sendViaBotLocationMessage(osmandBotId, shareInfo, TdApi.Location(locationMessage.lat, locationMessage.lon), device, shareType)
|
||||||
shareInfo.shouldSendViaBotMessage = false
|
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 url = "$BASE_URL/device/$sharingMode/send?lat=${loc.lat}&lon=${loc.lon}"
|
||||||
val builder = StringBuilder(url)
|
val builder = StringBuilder(url)
|
||||||
if (loc.bearing != 0.0) {
|
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) {
|
fun stopSendingLiveLocationToChat(shareInfo: TelegramSettings.ShareChatInfo) {
|
||||||
if (shareInfo.currentMapMessageId != -1L && shareInfo.chatId != -1L) {
|
if (shareInfo.currentMapMessageId != -1L && shareInfo.chatId != -1L) {
|
||||||
client?.send(
|
client?.send(
|
||||||
|
@ -831,7 +810,7 @@ class TelegramHelper private constructor() {
|
||||||
|
|
||||||
private fun recreateLiveLocationMessage(
|
private fun recreateLiveLocationMessage(
|
||||||
shareInfo: TelegramSettings.ShareChatInfo,
|
shareInfo: TelegramSettings.ShareChatInfo,
|
||||||
content: TdApi.InputMessageContent,locationMessage: LocationMessages.LocationMessage?
|
content: TdApi.InputMessageContent,locationMessage: LocationMessages.BufferMessage?
|
||||||
) {
|
) {
|
||||||
if (shareInfo.chatId != -1L) {
|
if (shareInfo.chatId != -1L) {
|
||||||
val array = LongArray(1)
|
val array = LongArray(1)
|
||||||
|
@ -861,106 +840,68 @@ class TelegramHelper private constructor() {
|
||||||
needRefreshActiveLiveLocationMessages = true
|
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
|
needRefreshActiveLiveLocationMessages = true
|
||||||
log.debug("sendNewLiveLocationMessage")
|
log.debug("sendNewLiveLocationMessage")
|
||||||
client?.send(
|
client?.send(TdApi.SendMessage(shareInfo.chatId, 0, false, true, null, content)) { obj ->
|
||||||
TdApi.SendMessage(shareInfo.chatId, 0, false, true, null, content)) { obj ->
|
if (locationMessage?.type == LocationMessages.TYPE_USER_TEXT || locationMessage?.type == LocationMessages.TYPE_BOT_TEXT) {
|
||||||
handleMapLocationMessageUpdate(obj, shareInfo, locationMessage)
|
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
|
|
||||||
}
|
|
||||||
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, 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) {
|
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 location = TdApi.Location(locationMessage.lat, locationMessage.lon)
|
||||||
val livePeriod = if (shareInfo.currentMessageLimit > (shareInfo.start + MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC)) {
|
val livePeriod =
|
||||||
|
if (shareInfo.currentMessageLimit > (shareInfo.start + MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC)) {
|
||||||
MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC
|
MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC
|
||||||
} else {
|
} else {
|
||||||
shareInfo.livePeriod.toInt()
|
shareInfo.livePeriod.toInt()
|
||||||
}
|
}
|
||||||
val content = TdApi.InputMessageLocation(location, livePeriod)
|
val content = TdApi.InputMessageLocation(location, livePeriod)
|
||||||
val msgId = shareInfo.currentMapMessageId
|
if (!shareInfo.pendingMapMessage) {
|
||||||
val timeAfterLastSendMessage = ((System.currentTimeMillis() / 1000) - shareInfo.lastSendMapMessageTime)
|
shareInfo.pendingMapMessage = true
|
||||||
log.debug("sendLiveLocationImpl - $msgId pendingMapMessage ${shareInfo.pendingMapMessage}")
|
client?.send(TdApi.SendMessage(shareInfo.chatId, 0, false, true, null, content)) { obj ->
|
||||||
if (msgId != -1L) {
|
handleMapLocationMessageUpdate(obj, shareInfo, locationMessage)
|
||||||
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 ->
|
|
||||||
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){
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleMapLocationMessageUpdate(obj: TdApi.Object, shareInfo: TelegramSettings.ShareChatInfo, location: LocationMessages.LocationMessage?) {
|
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.BufferMessage?) {
|
||||||
when (obj.constructor) {
|
when (obj.constructor) {
|
||||||
TdApi.Error.CONSTRUCTOR -> {
|
TdApi.Error.CONSTRUCTOR -> {
|
||||||
val error = obj as TdApi.Error
|
val error = obj as TdApi.Error
|
||||||
|
@ -980,7 +921,8 @@ class TelegramHelper private constructor() {
|
||||||
obj.sendingState?.constructor == TdApi.MessageSendingStateFailed.CONSTRUCTOR -> {
|
obj.sendingState?.constructor == TdApi.MessageSendingStateFailed.CONSTRUCTOR -> {
|
||||||
shareInfo.hasSharingError = true
|
shareInfo.hasSharingError = true
|
||||||
needRefreshActiveLiveLocationMessages = true
|
needRefreshActiveLiveLocationMessages = true
|
||||||
location?.status = LocationMessages.LocationMessage.STATUS_ERROR
|
shareInfo.pendingMapMessage = false
|
||||||
|
// location?.status = LocationMessages.LocationMessage.STATUS_ERROR
|
||||||
outgoingMessagesListeners.forEach {
|
outgoingMessagesListeners.forEach {
|
||||||
it.onSendLiveLocationError(-1, "Map location message ${obj.id} failed to send")
|
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 -> {
|
obj.sendingState?.constructor == TdApi.MessageSendingStatePending.CONSTRUCTOR -> {
|
||||||
shareInfo.pendingMapMessage = true
|
shareInfo.pendingMapMessage = true
|
||||||
shareInfo.lastSendMapMessageTime = obj.date
|
shareInfo.lastSendMapMessageTime = obj.date
|
||||||
location?.status = LocationMessages.LocationMessage.STATUS_PENDING
|
// location?.status = LocationMessages.LocationMessage.STATUS_PENDING
|
||||||
log.debug("handleMapLocationMessageUpdate - MessageSendingStatePending")
|
log.debug("handleMapLocationMessageUpdate - MessageSendingStatePending")
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
shareInfo.hasSharingError = false
|
shareInfo.hasSharingError = false
|
||||||
shareInfo.bufferedMessages--
|
shareInfo.pendingTdLib--
|
||||||
location?.messageId = obj.id
|
shareInfo.pendingMapMessage = false
|
||||||
location?.status = LocationMessages.LocationMessage.STATUS_SENT
|
// location?.messageId = obj.id
|
||||||
|
// location?.status = LocationMessages.LocationMessage.STATUS_SENT
|
||||||
outgoingMessagesListeners.forEach {
|
outgoingMessagesListeners.forEach {
|
||||||
it.onUpdateMessages(listOf(obj))
|
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) {
|
when (obj.constructor) {
|
||||||
TdApi.Error.CONSTRUCTOR -> {
|
TdApi.Error.CONSTRUCTOR -> {
|
||||||
val error = obj as TdApi.Error
|
val error = obj as TdApi.Error
|
||||||
|
@ -1024,9 +967,10 @@ class TelegramHelper private constructor() {
|
||||||
when {
|
when {
|
||||||
obj.sendingState?.constructor == TdApi.MessageSendingStateFailed.CONSTRUCTOR -> {
|
obj.sendingState?.constructor == TdApi.MessageSendingStateFailed.CONSTRUCTOR -> {
|
||||||
shareInfo.hasSharingError = true
|
shareInfo.hasSharingError = true
|
||||||
shareInfo.bufferedMessages--
|
shareInfo.pendingTdLib--
|
||||||
|
shareInfo.pendingTextMessage = false
|
||||||
needRefreshActiveLiveLocationMessages = true
|
needRefreshActiveLiveLocationMessages = true
|
||||||
location?.status = LocationMessages.LocationMessage.STATUS_ERROR
|
// location?.status = LocationMessages.LocationMessage.STATUS_ERROR
|
||||||
outgoingMessagesListeners.forEach {
|
outgoingMessagesListeners.forEach {
|
||||||
it.onSendLiveLocationError(-1, "Text location message ${obj.id} failed to send")
|
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 -> {
|
obj.sendingState?.constructor == TdApi.MessageSendingStatePending.CONSTRUCTOR -> {
|
||||||
shareInfo.pendingTextMessage = true
|
shareInfo.pendingTextMessage = true
|
||||||
shareInfo.lastSendTextMessageTime = obj.date
|
shareInfo.lastSendTextMessageTime = obj.date
|
||||||
location?.status = LocationMessages.LocationMessage.STATUS_PENDING
|
// location?.status = LocationMessages.LocationMessage.STATUS_PENDING
|
||||||
log.debug("handleTextLocationMessageUpdate - MessageSendingStatePending")
|
log.debug("handleTextLocationMessageUpdate - MessageSendingStatePending")
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
shareInfo.hasSharingError = false
|
shareInfo.hasSharingError = false
|
||||||
shareInfo.bufferedMessages--
|
shareInfo.pendingTdLib--
|
||||||
location?.messageId = obj.id
|
shareInfo.pendingTextMessage = false
|
||||||
location?.status = LocationMessages.LocationMessage.STATUS_SENT
|
// location?.messageId = obj.id
|
||||||
|
// location?.status = LocationMessages.LocationMessage.STATUS_SENT
|
||||||
outgoingMessagesListeners.forEach {
|
outgoingMessagesListeners.forEach {
|
||||||
it.onUpdateMessages(listOf(obj))
|
it.onUpdateMessages(listOf(obj))
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ import android.widget.*
|
||||||
import net.osmand.PlatformUtil
|
import net.osmand.PlatformUtil
|
||||||
import net.osmand.telegram.R
|
import net.osmand.telegram.R
|
||||||
import net.osmand.telegram.TelegramApplication
|
import net.osmand.telegram.TelegramApplication
|
||||||
|
import net.osmand.telegram.helpers.LocationMessages
|
||||||
import net.osmand.telegram.helpers.LocationMessages.LocationMessage
|
import net.osmand.telegram.helpers.LocationMessages.LocationMessage
|
||||||
import net.osmand.telegram.helpers.OsmandAidlHelper
|
import net.osmand.telegram.helpers.OsmandAidlHelper
|
||||||
import net.osmand.telegram.helpers.TelegramHelper
|
import net.osmand.telegram.helpers.TelegramHelper
|
||||||
|
@ -293,7 +294,7 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene
|
||||||
}
|
}
|
||||||
if (app.telegramService == null) {
|
if (app.telegramService == null) {
|
||||||
messages.forEach {
|
messages.forEach {
|
||||||
val locationMessage = OsmandLocationUtils.parseMessage(it, telegramHelper, LocationMessage.STATUS_PREPARED)
|
val locationMessage = OsmandLocationUtils.parseMessage(it, telegramHelper, LocationMessages.STATUS_PREPARED)
|
||||||
if (locationMessage != null) {
|
if (locationMessage != null) {
|
||||||
app.locationMessages.addIngoingMessage(locationMessage)
|
app.locationMessages.addIngoingMessage(locationMessage)
|
||||||
}
|
}
|
||||||
|
@ -349,8 +350,7 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene
|
||||||
fun logoutTelegram(silent: Boolean = false) {
|
fun logoutTelegram(silent: Boolean = false) {
|
||||||
if (telegramHelper.getTelegramAuthorizationState() == TelegramHelper.TelegramAuthorizationState.READY) {
|
if (telegramHelper.getTelegramAuthorizationState() == TelegramHelper.TelegramAuthorizationState.READY) {
|
||||||
if (app.isInternetConnectionAvailable) {
|
if (app.isInternetConnectionAvailable) {
|
||||||
// todo - why delete messages on logout?
|
app.locationMessages.clearBufferedMessages()
|
||||||
app.locationMessages.clearOutgoingMessages()
|
|
||||||
settings.clear()
|
settings.clear()
|
||||||
telegramHelper.logout()
|
telegramHelper.logout()
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -190,22 +190,22 @@ class TimelineTabFragment : Fragment() {
|
||||||
val res = mutableListOf<ListItem>()
|
val res = mutableListOf<ListItem>()
|
||||||
val ignoredUsersIds = ArrayList<Int>()
|
val ignoredUsersIds = ArrayList<Int>()
|
||||||
val currentUserId = telegramHelper.getCurrentUser()?.id
|
val currentUserId = telegramHelper.getCurrentUser()?.id
|
||||||
if (currentUserId != null) {
|
// if (currentUserId != null) {
|
||||||
val locationMessages = app.locationMessages.collectRecordedDataForUser(currentUserId, 0, start, end)
|
// 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?
|
// // todo - why do we need convert to gpx on update? Is locationMessages not enough to display info?
|
||||||
OsmandLocationUtils.convertLocationMessagesToGpxFiles(locationMessages, false).forEach {
|
// OsmandLocationUtils.convertLocationMessagesToGpxFiles(locationMessages, false).forEach {
|
||||||
TelegramUiHelper.gpxToChatItem(telegramHelper, it, true)?.also { chatItem ->
|
// TelegramUiHelper.gpxToChatItem(telegramHelper, it, true)?.also { chatItem ->
|
||||||
res.add(chatItem)
|
// res.add(chatItem)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
ignoredUsersIds.add(currentUserId)
|
// ignoredUsersIds.add(currentUserId)
|
||||||
}
|
// }
|
||||||
val locationMessages = app.locationMessages.collectRecordedDataForUsers(start, end, ignoredUsersIds)
|
// val locationMessages = app.locationMessages.collectRecordedDataForUsers(start, end, ignoredUsersIds)
|
||||||
OsmandLocationUtils.convertLocationMessagesToGpxFiles(locationMessages).forEach {
|
// OsmandLocationUtils.convertLocationMessagesToGpxFiles(locationMessages).forEach {
|
||||||
TelegramUiHelper.gpxToChatItem(telegramHelper, it,false)?.also { chatItem ->
|
// TelegramUiHelper.gpxToChatItem(telegramHelper, it,false)?.also { chatItem ->
|
||||||
res.add(chatItem)
|
// res.add(chatItem)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
adapter.items = sortAdapterItems(res)
|
adapter.items = sortAdapterItems(res)
|
||||||
}
|
}
|
||||||
|
|
|
@ -207,14 +207,14 @@ class UserGpxInfoFragment : BaseDialogFragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateGpxInfo() {
|
private fun updateGpxInfo() {
|
||||||
gpxFile = OsmandLocationUtils.convertLocationMessagesToGpxFiles(
|
// gpxFile = OsmandLocationUtils.convertLocationMessagesToGpxFiles(
|
||||||
app.locationMessages.collectRecordedDataForUser(
|
// app.locationMessages.collectRecordedDataForUser(
|
||||||
gpxFile.userId,
|
// gpxFile.userId,
|
||||||
gpxFile.chatId,
|
// gpxFile.chatId,
|
||||||
startCalendar.timeInMillis,
|
// startCalendar.timeInMillis,
|
||||||
endCalendar.timeInMillis
|
// endCalendar.timeInMillis
|
||||||
)
|
// )
|
||||||
).first()
|
// ).first()
|
||||||
updateGPXStatisticRow()
|
updateGPXStatisticRow()
|
||||||
updateDateAndTimeButtons()
|
updateDateAndTimeButtons()
|
||||||
updateGPXMap()
|
updateGPXMap()
|
||||||
|
|
|
@ -3,7 +3,9 @@ package net.osmand.telegram.utils
|
||||||
import android.os.AsyncTask
|
import android.os.AsyncTask
|
||||||
import net.osmand.Location
|
import net.osmand.Location
|
||||||
import net.osmand.telegram.TelegramApplication
|
import net.osmand.telegram.TelegramApplication
|
||||||
|
import net.osmand.telegram.helpers.LocationMessages
|
||||||
import net.osmand.telegram.helpers.LocationMessages.LocationMessage
|
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.TelegramHelper
|
||||||
import net.osmand.telegram.helpers.TelegramUiHelper
|
import net.osmand.telegram.helpers.TelegramUiHelper
|
||||||
import net.osmand.util.GeoPointParserUtil
|
import net.osmand.util.GeoPointParserUtil
|
||||||
|
@ -108,7 +110,7 @@ object OsmandLocationUtils {
|
||||||
if (parsedMessageContent != null) {
|
if (parsedMessageContent != null) {
|
||||||
locationMessage = LocationMessage(helper.getSenderMessageId(message), message.chatId, parsedMessageContent.lat,
|
locationMessage = LocationMessage(helper.getSenderMessageId(message), message.chatId, parsedMessageContent.lat,
|
||||||
parsedMessageContent.lon, parsedMessageContent.altitude, parsedMessageContent.speed, parsedMessageContent.hdop,
|
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
|
return locationMessage
|
||||||
}
|
}
|
||||||
|
@ -121,6 +123,10 @@ object OsmandLocationUtils {
|
||||||
return String.format(Locale.US, "%.5f, %.5f", sig.lat, sig.lon)
|
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 {
|
fun formatFullTime(ti: Long): String {
|
||||||
val dt = Date(ti)
|
val dt = Date(ti)
|
||||||
return UTC_DATE_FORMAT.format(dt) + " " + UTC_TIME_FORMAT.format(dt) + " UTC"
|
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)
|
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> {
|
fun convertLocationMessagesToGpxFiles(items: List<LocationMessage>, newGpxPerChat: Boolean = true): List<GPXUtilities.GPXFile> {
|
||||||
val dataTracks = ArrayList<GPXUtilities.GPXFile>()
|
val dataTracks = ArrayList<GPXUtilities.GPXFile>()
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue