remove unnecessary buttons and improve parsing location messages

This commit is contained in:
Chumva 2019-01-30 19:14:05 +02:00
parent dcdd62abcc
commit 30837f5fdb
14 changed files with 303 additions and 267 deletions

View file

@ -96,7 +96,7 @@
android:layout_height="1dp"
android:background="@color/app_bar_divider" />
<LinearLayout
<FrameLayout
android:id="@+id/date_row"
android:layout_width="match_parent"
android:layout_height="@dimen/list_header_height"
@ -106,13 +106,12 @@
android:paddingRight="@dimen/content_padding_standard">
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/date_start_btn"
android:layout_width="0dp"
android:id="@+id/date_btn"
android:layout_width="wrap_content"
android:layout_height="@dimen/dialog_button_height"
android:layout_gravity="center_vertical"
android:layout_gravity="center"
android:layout_marginEnd="@dimen/content_padding_half"
android:layout_marginRight="@dimen/content_padding_half"
android:layout_weight="1"
android:background="@drawable/btn_round_border"
android:drawablePadding="@dimen/content_padding_half"
android:ellipsize="end"
@ -120,38 +119,12 @@
android:maxLines="1"
android:paddingLeft="@dimen/image_button_padding"
android:paddingRight="@dimen/image_button_padding"
android:text="@string/start_date"
android:text="@string/shared_string_date"
android:textColor="?attr/ctrl_active_color"
android:textSize="@dimen/text_button_text_size"
app:typeface="@string/font_roboto_medium" />
<View
android:layout_width="16dp"
android:layout_height="1dp"
android:layout_gravity="center_vertical"
android:background="@color/app_bar_divider" />
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/date_end_btn"
android:layout_width="0dp"
android:layout_height="@dimen/dialog_button_height"
android:layout_gravity="center_vertical"
android:layout_marginLeft="@dimen/content_padding_half"
android:layout_marginStart="@dimen/content_padding_half"
android:layout_weight="1"
android:background="@drawable/btn_round_border"
android:drawablePadding="@dimen/content_padding_half"
android:ellipsize="end"
android:gravity="start|center_vertical"
android:maxLines="1"
android:paddingLeft="@dimen/image_button_padding"
android:paddingRight="@dimen/image_button_padding"
android:text="@string/end_date"
android:textColor="?attr/ctrl_active_color"
android:textSize="@dimen/text_button_text_size"
app:typeface="@string/font_roboto_medium" />
</LinearLayout>
</FrameLayout>
</android.support.design.widget.AppBarLayout>

View file

@ -1,4 +1,6 @@
<resources>
<string name="points_size">%1$d points</string>
<string name="shared_string_date">Date</string>
<string name="shared_string_collected">Collected</string>
<string name="gps_points">Gps points</string>
<string name="shared_string_sent">Sent</string>

View file

@ -276,10 +276,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)
if (locationMessage != null) {
app().locationMessages.addLocationMessage(locationMessage)
}
app().locationMessages.addNewLocationMessage(it)
}
}
@ -296,10 +293,7 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
app().settings.updateShareInfo(it)
app().shareLocationHelper.checkAndSendBufferMessagesToChat(it.chatId)
if (it.sendingState == null && (it.content is TdApi.MessageLocation || it.content is TdApi.MessageText)) {
val locationMessage = OsmandLocationUtils.parseMessage(it, app().telegramHelper)
if (locationMessage != null) {
app().locationMessages.addLocationMessage(locationMessage)
}
app().locationMessages.addNewLocationMessage(it)
}
}
}

View file

@ -245,31 +245,31 @@ class TelegramSettings(private val app: TelegramApplication) {
}
fun updateShareInfo(message: TdApi.Message) {
val shareChatInfo = shareChatsInfo[message.chatId]
val shareInfo = shareChatsInfo[message.chatId]
val content = message.content
if (shareChatInfo != null) {
if (shareInfo != null) {
when (content) {
is TdApi.MessageLocation -> {
val state = message.sendingState
if (state != null) {
if (state.constructor == TdApi.MessageSendingStatePending.CONSTRUCTOR) {
shareChatInfo.pendingMapMessage = true
shareInfo.pendingMapMessage = true
log.debug("updateShareInfo MAP ${message.id} MessageSendingStatePending")
shareChatInfo.oldMapMessageId = message.id
shareInfo.oldMapMessageId = message.id
} else if (state.constructor == TdApi.MessageSendingStateFailed.CONSTRUCTOR) {
shareChatInfo.hasSharingError = true
shareChatInfo.pendingMapMessage = false
shareInfo.hasSharingError = true
shareInfo.pendingMapMessage = false
log.debug("updateShareInfo MAP ${message.id} MessageSendingStateFailed")
}
} else {
log.debug("updateShareInfo MAP ${message.id} SUCCESS")
shareChatInfo.currentMapMessageId = message.id
shareChatInfo.pendingMapMessage = false
shareChatInfo.pendingTdLib--
shareChatInfo.lastSuccessfulSendTimeMs = Math.max(message.editDate, message.date) * 1000L
shareInfo.currentMapMessageId = message.id
shareInfo.pendingMapMessage = false
shareInfo.pendingTdLib--
shareInfo.lastSuccessfulSendTimeMs = Math.max(message.editDate, message.date) * 1000L
if (shareTypeValue == SHARE_TYPE_MAP) {
shareChatInfo.sentMessages++
shareInfo.sentMessages++
}
log.debug("updateShareInfo MAP ${message.id} SUCCESS pendingTdLib: ${shareInfo.pendingTdLib}")
}
}
is TdApi.MessageText -> {
@ -277,21 +277,21 @@ class TelegramSettings(private val app: TelegramApplication) {
if (state != null) {
if (state.constructor == TdApi.MessageSendingStatePending.CONSTRUCTOR) {
log.debug("updateShareInfo TEXT ${message.id} MessageSendingStatePending")
shareChatInfo.pendingTextMessage = true
shareChatInfo.oldTextMessageId = message.id
shareInfo.pendingTextMessage = true
shareInfo.oldTextMessageId = message.id
} else if (state.constructor == TdApi.MessageSendingStateFailed.CONSTRUCTOR) {
log.debug("updateShareInfo TEXT ${message.id} MessageSendingStateFailed")
shareChatInfo.hasSharingError = true
shareChatInfo.pendingTextMessage = false
shareInfo.hasSharingError = true
shareInfo.pendingTextMessage = false
}
} else {
log.debug("updateShareInfo TEXT ${message.id} SUCCESS")
shareChatInfo.currentTextMessageId = message.id
shareChatInfo.updateTextMessageId++
shareChatInfo.pendingTextMessage = false
shareChatInfo.pendingTdLib--
shareChatInfo.sentMessages++
shareChatInfo.lastSuccessfulSendTimeMs = Math.max(message.editDate, message.date) * 1000L
shareInfo.currentTextMessageId = message.id
shareInfo.updateTextMessageId++
shareInfo.pendingTextMessage = false
shareInfo.pendingTdLib--
shareInfo.sentMessages++
shareInfo.lastSuccessfulSendTimeMs = Math.max(message.editDate, message.date) * 1000L
log.debug("updateShareInfo TEXT ${message.id} SUCCESS pendingTdLib: ${shareInfo.pendingTdLib}")
}
}
}
@ -582,6 +582,7 @@ class TelegramSettings(private val app: TelegramApplication) {
obj.put(ShareChatInfo.PENDING_MAP_MESSAGE_KEY, chatInfo.pendingMapMessage)
obj.put(ShareChatInfo.COLLECTED_MESSAGES_KEY, chatInfo.collectedMessages)
obj.put(ShareChatInfo.SENT_MESSAGES_KEY, chatInfo.sentMessages)
obj.put(ShareChatInfo.PENDING_TDLIB_KEY, chatInfo.pendingTdLib)
jArray.put(obj)
}
jArray
@ -612,6 +613,7 @@ class TelegramSettings(private val app: TelegramApplication) {
pendingMapMessage = obj.optBoolean(ShareChatInfo.PENDING_MAP_MESSAGE_KEY)
collectedMessages = obj.optInt(ShareChatInfo.COLLECTED_MESSAGES_KEY)
sentMessages = obj.optInt(ShareChatInfo.SENT_MESSAGES_KEY)
pendingTdLib = obj.optInt(ShareChatInfo.PENDING_TDLIB_KEY)
}
shareChatsInfo[shareInfo.chatId] = shareInfo
}
@ -942,6 +944,7 @@ class TelegramSettings(private val app: TelegramApplication) {
internal const val PENDING_MAP_MESSAGE_KEY = "pendingMapMessage"
internal const val COLLECTED_MESSAGES_KEY = "collectedMessages"
internal const val SENT_MESSAGES_KEY = "sentMessages"
internal const val PENDING_TDLIB_KEY = "sentMessages"
}
}
}

View file

@ -6,6 +6,8 @@ import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
import net.osmand.PlatformUtil
import net.osmand.telegram.TelegramApplication
import net.osmand.telegram.utils.OsmandLocationUtils
import org.drinkless.td.libcore.telegram.TdApi
class LocationMessages(val app: TelegramApplication) {
@ -14,6 +16,8 @@ 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<BufferMessage>()
private var lastMessages = emptyList<LocationMessage>()
private val dbHelper: SQLiteHelper
init {
@ -21,12 +25,11 @@ class LocationMessages(val app: TelegramApplication) {
readBufferedMessages()
}
fun getPreparedMessages(): List<BufferMessage> {
fun getBufferedMessages(): List<BufferMessage> {
return bufferedMessages.sortedBy { it.time }
}
fun getPreparedMessagesForChat(chatId: Long): List<BufferMessage> {
log.debug("getPreparedMessagesForChat chatId")
fun getBufferedMessagesForChat(chatId: Long): List<BufferMessage> {
return bufferedMessages.filter { it.chatId==chatId }.sortedBy { it.time }
}
@ -35,8 +38,8 @@ class LocationMessages(val app: TelegramApplication) {
return dbHelper.getIngoingMessages(currentUserId, start, end)
}
fun getIngoingMessagesForUser(userId: Int, chatId: Long, start: Long, end: Long): List<LocationMessage> {
return dbHelper.getIngoingMessagesForUser(userId, chatId, start, end)
fun getMessagesForUserInChat(userId: Int, chatId: Long, start: Long, end: Long): List<LocationMessage> {
return dbHelper.getMessagesForUserInChat(userId, chatId, start, end)
}
fun getMessagesForUser(userId: Int, start: Long, end: Long): List<LocationMessage> {
@ -51,9 +54,19 @@ class LocationMessages(val app: TelegramApplication) {
dbHelper.addBufferedMessage(message)
}
fun addLocationMessage(message: LocationMessage) {
log.debug("addIngoingMessage $message")
dbHelper.addLocationMessage(message)
fun addNewLocationMessage(message: TdApi.Message) {
log.debug("addNewLocationMessage ${message.id}")
val type = OsmandLocationUtils.getMessageType(message, app.telegramHelper)
val previousMessage = lastMessages.firstOrNull { it.chatId == message.chatId && it.userId == message.senderUserId && it.type == type }
val locationMessage = OsmandLocationUtils.parseMessage(message, app.telegramHelper, previousMessage)
if (locationMessage != null) {
dbHelper.addLocationMessage(locationMessage)
val messages = mutableListOf(*this.lastMessages.toTypedArray())
messages.remove(previousMessage)
messages.add(locationMessage)
this.lastMessages = messages
}
}
fun clearBufferedMessages() {
@ -74,6 +87,10 @@ class LocationMessages(val app: TelegramApplication) {
this.bufferedMessages = dbHelper.getBufferedMessages()
}
private fun readLastMessages() {
this.lastMessages = dbHelper.getLastMessages()
}
private class SQLiteHelper(context: Context) :
SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) {
@ -98,7 +115,7 @@ class LocationMessages(val app: TelegramApplication) {
internal fun addLocationMessage(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.time, message.type))
message.hdop, message.bearing, message.time, message.type, message.messageId, message.distanceFromPrev))
}
internal fun getMessagesForUser(userId: Int, start: Long, end: Long): List<LocationMessage> {
@ -116,10 +133,23 @@ class LocationMessages(val app: TelegramApplication) {
return res
}
internal fun getPreviousMessage(userId: Int, chatId: Long): LocationMessage? {
var res:LocationMessage? = null
readableDatabase?.rawQuery(
"$TIMELINE_TABLE_SELECT WHERE $COL_USER_ID = ? AND $COL_CHAT_ID = ? ORDER BY $COL_TIME DESC LIMIT 1",
arrayOf(userId.toString(), chatId.toString()))?.apply {
if (moveToFirst()) {
res = readLocationMessage(this@apply)
}
close()
}
return res
}
internal fun getIngoingMessages(currentUserId: Int, start: Long, end: Long): List<LocationMessage> {
val res = arrayListOf<LocationMessage>()
readableDatabase?.rawQuery(
"$TIMELINE_TABLE_SELECT WHERE $COL_USER_ID != ? AND $COL_CHAT_ID = ? AND $COL_TIME BETWEEN $start AND $end ORDER BY $COL_TIME ASC ",
"$TIMELINE_TABLE_SELECT WHERE $COL_USER_ID != ? AND $COL_TIME BETWEEN $start AND $end ORDER BY $COL_USER_ID ASC, $COL_CHAT_ID ASC, $COL_TIME ASC ",
arrayOf(currentUserId.toString()))?.apply {
if (moveToFirst()) {
do {
@ -131,11 +161,11 @@ class LocationMessages(val app: TelegramApplication) {
return res
}
internal fun getIngoingMessagesForUser(userId: Int, chatId: Long, start: Long, end: Long): List<LocationMessage> {
internal fun getMessagesForUserInChat(userId: Int, chatId: Long, start: Long, end: Long): List<LocationMessage> {
val res = arrayListOf<LocationMessage>()
readableDatabase?.rawQuery(
"$TIMELINE_TABLE_SELECT WHERE $COL_USER_ID = ? AND $COL_CHAT_ID = ? AND $COL_TIME BETWEEN $start AND $end ORDER BY $COL_TIME ASC ",
arrayOf(userId.toString(), chatId.toString(), start.toString(), end.toString()))?.apply {
arrayOf(userId.toString(), chatId.toString()))?.apply {
if (moveToFirst()) {
do {
res.add(readLocationMessage(this@apply))
@ -159,6 +189,19 @@ class LocationMessages(val app: TelegramApplication) {
return res
}
internal fun getLastMessages(): List<LocationMessage> {
val res = arrayListOf<LocationMessage>()
readableDatabase?.rawQuery(TIMELINE_TABLE_SELECT, null)?.apply {
if (moveToFirst()) {
do {
res.add(readLocationMessage(this@apply))
} while (moveToNext())
}
close()
}
return res
}
internal fun readLocationMessage(cursor: Cursor): LocationMessage {
val userId = cursor.getInt(0)
val chatId = cursor.getLong(1)
@ -170,8 +213,10 @@ class LocationMessages(val app: TelegramApplication) {
val bearing = cursor.getDouble(7)
val date = cursor.getLong(8)
val type = cursor.getInt(9)
val messageId = cursor.getLong(10)
val distanceFromPrev = cursor.getDouble(11)
return LocationMessage(userId, chatId, lat, lon, altitude, speed, hdop, bearing, date, type)
return LocationMessage(userId, chatId, lat, lon, altitude, speed, hdop, bearing, date, type, messageId, distanceFromPrev)
}
internal fun readBufferMessage(cursor: Cursor): BufferMessage {
@ -213,7 +258,7 @@ class LocationMessages(val app: TelegramApplication) {
companion object {
private const val DATABASE_NAME = "location_messages"
private const val DATABASE_VERSION = 4
private const val DATABASE_VERSION = 5
private const val TIMELINE_TABLE_NAME = "timeline"
private const val BUFFER_TABLE_NAME = "buffer"
@ -229,18 +274,19 @@ class LocationMessages(val app: TelegramApplication) {
private const val COL_BEARING = "bearing"
private const val COL_TYPE = "type" // 0 = user map message, 1 = user text message, 2 = bot map message, 3 = bot text message
private const val COL_MESSAGE_ID = "message_id"
private const val COL_DISTANCE_FROM_PREV = "distance_from_prev"
private const val DATE_INDEX = "date_index"
// 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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
("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, $COL_DISTANCE_FROM_PREV) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
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 )")
("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, $COL_DISTANCE_FROM_PREV double )")
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"
"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, $COL_DISTANCE_FROM_PREV FROM $TIMELINE_TABLE_NAME"
private const val TIMELINE_TABLE_CLEAR = "DELETE FROM $TIMELINE_TABLE_NAME"
@ -274,7 +320,9 @@ class LocationMessages(val app: TelegramApplication) {
val hdop: Double,
val bearing: Double,
val time: Long,
val type: Int)
val type: Int,
val messageId: Long,
val distanceFromPrev: Double)
data class BufferMessage (
val chatId: Long,

View file

@ -96,10 +96,9 @@ class ShareLocationHelper(private val app: TelegramApplication) {
}
fun checkAndSendBufferMessagesToChat(chatId: Long) {
log.debug("checkAndSendBufferMessagesToChat $chatId")
val shareInfo = app.settings.getChatsShareInfo()[chatId]
if (shareInfo != null && shareInfo.pendingTdLib < 10) {
app.locationMessages.getPreparedMessagesForChat(shareInfo.chatId).forEach {
app.locationMessages.getBufferedMessagesForChat(shareInfo.chatId).forEach {
if (it.type == LocationMessages.TYPE_USER_TEXT && !shareInfo.pendingTextMessage && shareInfo.currentTextMessageId != -1L) {
app.telegramHelper.editTextLocation(shareInfo, it)
app.locationMessages.removeBufferedMessage(it)
@ -169,7 +168,7 @@ class ShareLocationHelper(private val app: TelegramApplication) {
log.debug("checkAndSendBufferMessages")
app.settings.getChatsShareInfo().forEach loop@{ (chatId, shareInfo) ->
if (shareInfo.pendingTdLib < 10) {
app.locationMessages.getPreparedMessagesForChat(chatId).forEach {
app.locationMessages.getBufferedMessagesForChat(chatId).forEach {
if (it.type == LocationMessages.TYPE_USER_TEXT && !shareInfo.pendingTextMessage && shareInfo.currentTextMessageId != -1L) {
app.telegramHelper.editTextLocation(shareInfo, it)
app.locationMessages.removeBufferedMessage(it)

View file

@ -11,7 +11,7 @@ import net.osmand.telegram.TelegramApplication
import net.osmand.telegram.helpers.TelegramUiHelper.ListItem
import net.osmand.telegram.utils.AndroidUtils
import net.osmand.telegram.utils.OsmandLocationUtils
import net.osmand.telegram.utils.OsmandLocationUtils.MessageUserTextLocation
import net.osmand.telegram.utils.OsmandLocationUtils.MessageUserLocation
import net.osmand.telegram.utils.OsmandLocationUtils.MessageOsmAndBotLocation
import org.drinkless.td.libcore.telegram.TdApi
import java.io.File
@ -81,7 +81,7 @@ class ShowLocationHelper(private val app: TelegramApplication) {
val content = message.content
val date = OsmandLocationUtils.getLastUpdatedTime(message)
val stale = System.currentTimeMillis() / 1000 - date > app.settings.staleLocTime
if (chatTitle != null && (content is TdApi.MessageLocation || (content is MessageUserTextLocation && content.isValid()))) {
if (chatTitle != null && (content is TdApi.MessageLocation || (content is MessageUserLocation && content.isValid()))) {
var userName = ""
var photoPath: String? = null
val user = telegramHelper.getUser(message.senderUserId)
@ -106,7 +106,7 @@ class ShowLocationHelper(private val app: TelegramApplication) {
val params = generatePointParams(photoPath, stale)
val aLatLon = when (content) {
is TdApi.MessageLocation -> ALatLon(content.location.latitude, content.location.longitude)
is MessageUserTextLocation -> ALatLon(content.lat, content.lon)
is MessageUserLocation -> ALatLon(content.lat, content.lon)
else -> null
}
if (aLatLon != null) {
@ -251,7 +251,7 @@ class ShowLocationHelper(private val app: TelegramApplication) {
private fun removeMapPoint(chatId: Long, message: TdApi.Message) {
val content = message.content
if (content is TdApi.MessageLocation || content is MessageUserTextLocation) {
if (content is TdApi.MessageLocation || content is MessageUserLocation) {
osmandAidlHelper.removeMapPoint(MAP_LAYER_ID, "${chatId}_${message.senderUserId}")
} else if (content is MessageOsmAndBotLocation) {
osmandAidlHelper.removeMapPoint(MAP_LAYER_ID, "${chatId}_${content.name}")

View file

@ -9,7 +9,7 @@ import net.osmand.telegram.utils.GRAYSCALE_PHOTOS_EXT
import net.osmand.telegram.utils.OsmandLocationUtils
import net.osmand.telegram.utils.OsmandLocationUtils.DEVICE_PREFIX
import net.osmand.telegram.utils.OsmandLocationUtils.MessageOsmAndBotLocation
import net.osmand.telegram.utils.OsmandLocationUtils.MessageUserTextLocation
import net.osmand.telegram.utils.OsmandLocationUtils.MessageUserLocation
import net.osmand.telegram.utils.OsmandLocationUtils.USER_TEXT_LOCATION_TITLE
import net.osmand.telegram.utils.OsmandLocationUtils.getLastUpdatedTime
import net.osmand.telegram.utils.OsmandLocationUtils.parseOsmAndBotLocation
@ -396,7 +396,7 @@ class TelegramHelper private constructor() {
private fun isUserLocationMessage(message: TdApi.Message): Boolean {
val cont = message.content
return (cont is MessageUserTextLocation || cont is TdApi.MessageLocation)
return (cont is MessageUserLocation || cont is TdApi.MessageLocation)
}
private fun hasLocalUserPhoto(user: TdApi.User): Boolean {
@ -688,10 +688,6 @@ class TelegramHelper private constructor() {
}
}
fun loadMessage(chatId: Long, messageId: Long) {
requestMessage(chatId, messageId, this@TelegramHelper::addNewMessage)
}
private fun requestMessage(chatId: Long, messageId: Long, onComplete: (TdApi.Message) -> Unit) {
client?.send(TdApi.GetMessage(chatId, messageId)) { obj ->
if (obj is TdApi.Message) {
@ -703,6 +699,9 @@ class TelegramHelper private constructor() {
private fun addNewMessage(message: TdApi.Message) {
lastTelegramUpdateTime = Math.max(lastTelegramUpdateTime, Math.max(message.date, message.editDate))
if (message.isAppropriate()) {
if (message.isOutgoing) {
return
}
log.debug("addNewMessage: ${message.id}")
val fromBot = isOsmAndBot(message.senderUserId)
val viaBot = isOsmAndBot(message.viaBotUserId)
@ -716,21 +715,15 @@ class TelegramHelper private constructor() {
} else if (oldContent is TdApi.MessageLocation && (fromBot || viaBot)) {
message.content = parseOsmAndBotLocation(message)
}
if (message.isOutgoing) {
outgoingMessagesListeners.forEach {
it.onUpdateMessages(listOf(message))
}
} else {
removeOldMessages(message, fromBot, viaBot)
val oldMessage = usersLocationMessages.values.firstOrNull { getSenderMessageId(it) == getSenderMessageId(message) && !fromBot && !viaBot }
val hasNewerMessage = oldMessage != null && (Math.max(message.editDate, message.date) < Math.max(oldMessage.editDate, oldMessage.date))
if (!hasNewerMessage) {
usersLocationMessages[message.id] = message
}
incomingMessagesListeners.forEach {
if (!hasNewerMessage || it is TelegramService) {
it.onReceiveChatLocationMessages(message.chatId, message)
}
removeOldMessages(message, fromBot, viaBot)
val oldMessage = usersLocationMessages.values.firstOrNull { getSenderMessageId(it) == getSenderMessageId(message) && !fromBot && !viaBot }
val hasNewerMessage = oldMessage != null && (Math.max(message.editDate, message.date) < Math.max(oldMessage.editDate, oldMessage.date))
if (!hasNewerMessage) {
usersLocationMessages[message.id] = message
}
incomingMessagesListeners.forEach {
if (!hasNewerMessage || it is TelegramService) {
it.onReceiveChatLocationMessages(message.chatId, message)
}
}
}
@ -908,7 +901,7 @@ class TelegramHelper private constructor() {
private fun handleMapLocationMessageUpdate(obj: TdApi.Object, shareInfo: TelegramSettings.ShareChatInfo) {
when (obj.constructor) {
TdApi.Error.CONSTRUCTOR -> {
log.debug("handleMapLocationMessageUpdate - ERROR")
log.debug("handleMapLocationMessageUpdate - ERROR $obj")
val error = obj as TdApi.Error
needRefreshActiveLiveLocationMessages = true
if (error.code == MESSAGE_CANNOT_BE_EDITED_ERROR_CODE) {
@ -973,7 +966,6 @@ class TelegramHelper private constructor() {
when {
obj.sendingState?.constructor == TdApi.MessageSendingStateFailed.CONSTRUCTOR -> {
shareInfo.hasSharingError = true
shareInfo.pendingTdLib--
shareInfo.pendingTextMessage = false
needRefreshActiveLiveLocationMessages = true
log.debug("handleTextLocationMessageUpdate - MessageSendingStateFailed")
@ -1317,26 +1309,10 @@ class TelegramHelper private constructor() {
}
}
}
TdApi.UpdateMessageEdited.CONSTRUCTOR -> {
val updateMessageEdited = obj as TdApi.UpdateMessageEdited
val message = usersLocationMessages[updateMessageEdited.messageId]
if (message == null) {
updateMessageEdited.apply {
requestMessage(chatId, messageId, this@TelegramHelper::addNewMessage)
}
} else {
synchronized(message) {
message.editDate = updateMessageEdited.editDate
lastTelegramUpdateTime = Math.max(message.date, message.editDate)
}
incomingMessagesListeners.forEach {
it.updateLocationMessages()
}
}
}
TdApi.UpdateMessageContent.CONSTRUCTOR -> {
val updateMessageContent = obj as TdApi.UpdateMessageContent
val message = usersLocationMessages[updateMessageContent.messageId]
log.debug("UpdateMessageContent " + updateMessageContent.messageId)
if (message == null) {
updateMessageContent.apply {
requestMessage(chatId, messageId, this@TelegramHelper::addNewMessage)
@ -1356,7 +1332,6 @@ class TelegramHelper private constructor() {
newContent
}
}
log.debug("UpdateMessageContent " + message.senderUserId)
incomingMessagesListeners.forEach {
it.onReceiveChatLocationMessages(message.chatId, message)
}
@ -1364,6 +1339,7 @@ class TelegramHelper private constructor() {
}
TdApi.UpdateNewMessage.CONSTRUCTOR -> {
addNewMessage((obj as TdApi.UpdateNewMessage).message)
log.debug("UpdateNewMessage " + obj.message.id)
}
TdApi.UpdateMessageMentionRead.CONSTRUCTOR -> {
val updateChat = obj as TdApi.UpdateMessageMentionRead

View file

@ -6,11 +6,10 @@ import android.widget.ImageView
import net.osmand.data.LatLon
import net.osmand.telegram.R
import net.osmand.telegram.TelegramApplication
import net.osmand.telegram.utils.OsmandLocationUtils
import net.osmand.telegram.utils.OsmandLocationUtils.MessageUserTextLocation
import net.osmand.telegram.utils.OsmandLocationUtils.MessageOsmAndBotLocation
import net.osmand.telegram.utils.GPXUtilities
import net.osmand.telegram.utils.GPXUtilities.GPXFile
import net.osmand.telegram.utils.OsmandLocationUtils
import net.osmand.telegram.utils.OsmandLocationUtils.MessageOsmAndBotLocation
import net.osmand.telegram.utils.OsmandLocationUtils.MessageUserLocation
import org.drinkless.td.libcore.telegram.TdApi
object TelegramUiHelper {
@ -71,7 +70,7 @@ object TelegramUiHelper {
val content = message.content
if (content is TdApi.MessageLocation) {
res.latLon = LatLon(content.location.latitude, content.location.longitude)
} else if (content is MessageUserTextLocation) {
} else if (content is MessageUserLocation) {
res.latLon = LatLon(content.lat, content.lon)
}
}
@ -112,7 +111,7 @@ object TelegramUiHelper {
val content = message.content
return when (content) {
is MessageOsmAndBotLocation -> botMessageToLocationItem(chat, content)
is MessageUserTextLocation -> locationMessageToLocationItem(helper, chat, message)
is MessageUserLocation -> locationMessageToLocationItem(helper, chat, message)
is TdApi.MessageLocation -> locationMessageToLocationItem(helper, chat, message)
else -> null
}
@ -127,7 +126,7 @@ object TelegramUiHelper {
return when (content) {
is MessageOsmAndBotLocation -> botMessageToChatItem(helper, chat, content)
is TdApi.MessageLocation -> locationMessageToChatItem(helper, chat, message)
is MessageUserTextLocation -> locationMessageToChatItem(helper, chat, message)
is MessageUserLocation -> locationMessageToChatItem(helper, chat, message)
else -> null
}
}
@ -167,7 +166,7 @@ object TelegramUiHelper {
name = TelegramUiHelper.getUserName(user)
latLon = when (content) {
is TdApi.MessageLocation -> LatLon(content.location.latitude, content.location.longitude)
is MessageUserTextLocation -> LatLon(content.lat, content.lon)
is MessageUserLocation -> LatLon(content.lat, content.lon)
else -> null
}
photoPath = helper.getUserPhotoPath(user)
@ -213,7 +212,7 @@ object TelegramUiHelper {
name = TelegramUiHelper.getUserName(user)
latLon = when (content) {
is TdApi.MessageLocation -> LatLon(content.location.latitude, content.location.longitude)
is MessageUserTextLocation -> LatLon(content.lat, content.lon)
is MessageUserLocation -> LatLon(content.lat, content.lon)
else -> null
}
if (helper.isGroup(chat)) {
@ -257,6 +256,33 @@ object TelegramUiHelper {
}
}
fun locationMessagesToChatItem(
helper: TelegramHelper,
messages: List<LocationMessages.LocationMessage>
): LocationMessagesChatItem? {
val message = messages.firstOrNull()
val user = helper.getUser(message?.userId ?: -1) ?: return null
val chat = helper.getChat(message?.chatId ?: -1) ?: return null
return LocationMessagesChatItem().apply {
chatId = chat.id
chatTitle = chat.title
locationMessages = messages
name = TelegramUiHelper.getUserName(user)
if (helper.isGroup(chat)) {
photoPath = helper.getUserPhotoPath(user)
groupPhotoPath = chat.photo?.small?.local?.path
} else {
photoPath = user.profilePhoto?.small?.local?.path
}
grayscalePhotoPath = helper.getUserGreyPhotoPath(user)
placeholderId = R.drawable.img_user_picture
userId = user.id
privateChat = helper.isPrivateChat(chat) || helper.isSecretChat(chat)
chatWithBot = helper.isBot(userId)
lastUpdated = (messages.maxBy { it.time }?.time ?: -1).toInt()
}
}
private fun gpxToUserGpxChatItem(
helper: TelegramHelper,
gpx: GPXFile
@ -340,6 +366,24 @@ object TelegramUiHelper {
override fun getVisibleName() = chatTitle
}
class LocationMessagesChatItem : ListItem() {
var locationMessages: List<LocationMessages.LocationMessage> = emptyList()
internal set
var groupPhotoPath: String? = null
internal set
var privateChat: Boolean = false
internal set
var chatWithBot: Boolean = false
internal set
override fun canBeOpenedOnMap() = latLon != null
override fun getMapPointId() = "${chatId}_$userId"
override fun getVisibleName() = chatTitle
}
class LocationItem : ListItem() {
override fun canBeOpenedOnMap() = latLon != null

View file

@ -294,10 +294,7 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene
}
if (app.telegramService == null) {
messages.forEach {
val locationMessage = OsmandLocationUtils.parseMessage(it, telegramHelper)
if (locationMessage != null) {
app.locationMessages.addLocationMessage(locationMessage)
}
app.locationMessages.addNewLocationMessage(it)
}
}
}

View file

@ -231,7 +231,6 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
override fun onResume() {
super.onResume()
updateCurrentUserPhoto()
telegramHelper.getActiveLiveLocationMessages(null)
updateContent()
updateEnable = true
startHandler()
@ -719,7 +718,8 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
}
holder.gpsPointsCollected?.apply {
if (shareInfo != null) {
text = "${shareInfo.collectedMessages}"
val bufferedMessages = shareInfo.pendingTdLib + app.locationMessages.getBufferedMessagesForChat(shareInfo.chatId).size
text = "$bufferedMessages"
}
}
holder.gpsPointsSent?.apply {

View file

@ -18,12 +18,12 @@ import android.widget.TextView
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.TelegramUiHelper
import net.osmand.telegram.helpers.TelegramUiHelper.ListItem
import net.osmand.telegram.ui.TimelineTabFragment.LiveNowListAdapter.BaseViewHolder
import net.osmand.telegram.utils.AndroidUtils
import net.osmand.telegram.utils.OsmandFormatter
import net.osmand.telegram.utils.OsmandLocationUtils
import java.util.*
@ -39,8 +39,7 @@ class TimelineTabFragment : Fragment() {
private lateinit var adapter: LiveNowListAdapter
private lateinit var dateStartBtn: TextView
private lateinit var dateEndBtn: TextView
private lateinit var dateBtn: TextView
private lateinit var mainView: View
private var start = 0L
@ -77,21 +76,13 @@ class TimelineTabFragment : Fragment() {
monitoringTv.setText(if (monitoringEnabled) R.string.monitoring_is_enabled else R.string.monitoring_is_disabled)
}
dateStartBtn = mainView.findViewById<TextView>(R.id.date_start_btn).apply {
dateBtn = mainView.findViewById<TextView>(R.id.date_btn).apply {
setOnClickListener {
selectStartDate()
selectDate()
}
setCompoundDrawablesWithIntrinsicBounds(getPressedStateIcon(R.drawable.ic_action_date_start), null, null, null)
setTextColor(AndroidUtils.createPressedColorStateList(app, true, R.color.ctrl_active_light, R.color.ctrl_light))
}
dateEndBtn = mainView.findViewById<TextView>(R.id.date_end_btn).apply {
setOnClickListener {
selectEndDate()
}
setCompoundDrawablesWithIntrinsicBounds(getPressedStateIcon(R.drawable.ic_action_date_add), null, null, null)
}
setupBtnTextColor(dateStartBtn)
setupBtnTextColor(dateEndBtn)
return mainView
}
@ -107,24 +98,28 @@ class TimelineTabFragment : Fragment() {
updateEnable = false
}
private fun setupBtnTextColor(textView: TextView) {
textView.setTextColor(AndroidUtils.createPressedColorStateList(app, true, R.color.ctrl_active_light, R.color.ctrl_light))
}
private fun selectStartDate() {
private fun selectDate() {
val dateFromDialog =
DatePickerDialog.OnDateSetListener { _, year, monthOfYear, dayOfMonth ->
val from = Calendar.getInstance()
from.set(Calendar.YEAR, year)
from.set(Calendar.MONTH, monthOfYear)
from.set(Calendar.DAY_OF_MONTH, dayOfMonth)
from.set(Calendar.HOUR_OF_DAY, 0)
from.clear(Calendar.MINUTE)
from.clear(Calendar.SECOND)
from.clear(Calendar.MILLISECOND)
start = from.timeInMillis
from.set(Calendar.HOUR_OF_DAY, 23)
from.set(Calendar.MINUTE, 59)
from.set(Calendar.SECOND, 59)
from.set(Calendar.MILLISECOND, 999)
end = from.timeInMillis
updateList()
updateDateButtons()
updateDateButton()
}
val startCalendar = Calendar.getInstance()
startCalendar.timeInMillis = start
@ -135,34 +130,8 @@ class TimelineTabFragment : Fragment() {
).show()
}
private fun selectEndDate() {
val dateFromDialog =
DatePickerDialog.OnDateSetListener { _, year, monthOfYear, dayOfMonth ->
val from = Calendar.getInstance()
from.set(Calendar.YEAR, year)
from.set(Calendar.MONTH, monthOfYear)
from.set(Calendar.DAY_OF_MONTH, dayOfMonth)
from.set(Calendar.HOUR_OF_DAY, 23)
from.set(Calendar.MINUTE, 59)
from.set(Calendar.SECOND, 59)
from.set(Calendar.MILLISECOND, 999)
end = from.timeInMillis
updateList()
updateDateButtons()
}
val endCalendar = Calendar.getInstance()
endCalendar.timeInMillis = end
DatePickerDialog(context, dateFromDialog,
endCalendar.get(Calendar.YEAR),
endCalendar.get(Calendar.MONTH),
endCalendar.get(Calendar.DAY_OF_MONTH)
).show()
}
private fun updateDateButtons() {
dateStartBtn.text = OsmandFormatter.getFormattedDate(start / 1000)
dateEndBtn.text = OsmandFormatter.getFormattedDate(end / 1000)
dateEndBtn.setCompoundDrawablesWithIntrinsicBounds(getPressedStateIcon(R.drawable.ic_action_date_end), null, null, null)
private fun updateDateButton() {
dateBtn.text = OsmandFormatter.getFormattedDate(start / 1000)
}
private fun getPressedStateIcon(@DrawableRes iconId: Int): Drawable? {
@ -188,22 +157,19 @@ class TimelineTabFragment : Fragment() {
private fun updateList() {
val res = mutableListOf<ListItem>()
val ignoredUsersIds = ArrayList<Int>()
val currentUserId = telegramHelper.getCurrentUser()?.id
if (currentUserId != null) {
val outgoingMessages = app.locationMessages.getMessagesForUser(currentUserId, start, end)
// todo - why do we need convert to gpx on update? Is locationMessages not enough to display info?
OsmandLocationUtils.convertLocationMessagesToGpxFiles(outgoingMessages, false).forEach {
TelegramUiHelper.gpxToChatItem(telegramHelper, it, true)?.also { chatItem ->
TelegramUiHelper.locationMessagesToChatItem(telegramHelper, outgoingMessages)?.also { chatItem ->
res.add(chatItem)
}
}
ignoredUsersIds.add(currentUserId)
val ingoingMessages = app.locationMessages.getIngoingMessages(currentUserId, start, end)
OsmandLocationUtils.convertLocationMessagesToGpxFiles(ingoingMessages).forEach {
TelegramUiHelper.gpxToChatItem(telegramHelper, it, false)?.also { chatItem ->
res.add(chatItem)
}
val emm = ingoingMessages.distinctBy { Pair(it.userId, it.chatId) }
emm.forEach { message ->
TelegramUiHelper.locationMessagesToChatItem(telegramHelper,
ingoingMessages.filter { it.chatId == message.chatId && it.userId == message.userId })?.also { chatItem ->
res.add(chatItem)
}
}
}
@ -245,24 +211,17 @@ class TimelineTabFragment : Fragment() {
holder.bottomShadow?.visibility = if (lastItem) View.VISIBLE else View.GONE
holder.lastTelegramUpdateTime?.visibility = View.GONE
if (item is TelegramUiHelper.GpxChatItem) {
val gpx = item.gpxFile
val groupDescrRowVisible = (!item.privateChat || item.chatWithBot) && item.userId != currentUserId
if (groupDescrRowVisible) {
holder.groupDescrContainer?.visibility = View.VISIBLE
holder.groupTitle?.text = item.getVisibleName()
TelegramUiHelper.setupPhoto(app, holder.groupImage, item.groupPhotoPath, item.placeholderId, false)
} else {
holder.groupDescrContainer?.visibility = View.GONE
}
if (item is TelegramUiHelper.LocationMessagesChatItem) {
val distance = OsmandFormatter.getFormattedDistance(getDistance(item.locationMessages),app)
val name = if ((!item.privateChat || item.chatWithBot) && item.userId != currentUserId) item.getVisibleName() else ""
holder.groupDescrContainer?.visibility = View.VISIBLE
holder.groupTitle?.text = "$distance (${getString(R.string.points_size, item.locationMessages.size)}) $name"
TelegramUiHelper.setupPhoto(app, holder.groupImage, item.groupPhotoPath, item.placeholderId, false)
holder.userRow?.setOnClickListener {
if (gpx != null) {
childFragmentManager.also {
UserGpxInfoFragment.showInstance(it, gpx, start, end)
}
childFragmentManager.also {
UserGpxInfoFragment.showInstance(it, item.userId, item.chatId, start, end)
}
}
holder.imageButton?.visibility = View.GONE
holder.showOnMapRow?.visibility = View.GONE
holder.bottomDivider?.visibility = if (lastItem) View.GONE else View.VISIBLE
@ -270,6 +229,14 @@ class TimelineTabFragment : Fragment() {
}
}
private fun getDistance(messages: List<LocationMessages.LocationMessage>): Float {
var dist = 0.0
messages.forEach {
dist += it.distanceFromPrev
}
return dist.toFloat()
}
override fun getItemCount() = items.size
inner class BaseViewHolder(view: View) : RecyclerView.ViewHolder(view) {

View file

@ -37,7 +37,7 @@ class UserGpxInfoFragment : BaseDialogFragment() {
private val uiUtils get() = app.uiUtils
private lateinit var gpxFile: GPXUtilities.GPXFile
private var gpxFile = GPXUtilities.GPXFile()
private lateinit var dateStartBtn: TextView
private lateinit var timeStartBtn: TextView
@ -52,6 +52,9 @@ class UserGpxInfoFragment : BaseDialogFragment() {
private var startCalendar = Calendar.getInstance()
private var endCalendar = Calendar.getInstance()
private var userId = -1
private var chatId = -1L
override fun onCreateView(
inflater: LayoutInflater,
parent: ViewGroup?,
@ -62,8 +65,6 @@ class UserGpxInfoFragment : BaseDialogFragment() {
readFromBundle(savedInstanceState ?: arguments)
val userId = gpxFile.userId
val user = app.telegramHelper.getUser(userId)
if (user != null) {
mainView.findViewById<TextView>(R.id.title).text = TelegramUiHelper.getUserName(user)
@ -79,8 +80,6 @@ class UserGpxInfoFragment : BaseDialogFragment() {
}
})
updateGPXMap()
val backBtn = mainView.findViewById<ImageView>(R.id.back_button)
backBtn.setImageDrawable(uiUtils.getThemedIcon(R.drawable.ic_arrow_back))
backBtn.setOnClickListener {
@ -169,6 +168,8 @@ class UserGpxInfoFragment : BaseDialogFragment() {
}
}
updateGpxInfo()
return mainView
}
@ -197,6 +198,8 @@ class UserGpxInfoFragment : BaseDialogFragment() {
private fun readFromBundle(bundle: Bundle?) {
bundle?.also {
userId = it.getInt(USER_ID_KEY)
chatId = it.getLong(CHAT_ID_KEY)
startCalendar.timeInMillis = it.getLong(START_KEY)
endCalendar.timeInMillis = it.getLong(END_KEY)
}
@ -207,14 +210,10 @@ class UserGpxInfoFragment : BaseDialogFragment() {
}
private fun updateGpxInfo() {
// gpxFile = OsmandLocationUtils.convertLocationMessagesToGpxFiles(
// app.locationMessages.collectRecordedDataForUser(
// gpxFile.userId,
// gpxFile.chatId,
// startCalendar.timeInMillis,
// endCalendar.timeInMillis
// )
// ).first()
val emm = app.locationMessages.getMessagesForUserInChat(
userId, chatId, startCalendar.timeInMillis, endCalendar.timeInMillis)
gpxFile = OsmandLocationUtils.convertLocationMessagesToGpxFiles(emm).firstOrNull()?:GPXUtilities.GPXFile()
updateGPXStatisticRow()
updateDateAndTimeButtons()
updateGPXMap()
@ -308,18 +307,21 @@ class UserGpxInfoFragment : BaseDialogFragment() {
private const val TAG = "UserGpxInfoFragment"
private const val START_KEY = "start_key"
private const val END_KEY = "end_key"
private const val USER_ID_KEY = "user_id_key"
private const val CHAT_ID_KEY = "chat_id_key"
private const val GPX_TRACK_COLOR = -65536
fun showInstance(fm: FragmentManager, gpxFile: GPXUtilities.GPXFile, start: Long, end: Long): Boolean {
fun showInstance(fm: FragmentManager,userId:Int,chatId:Long, start: Long, end: Long): Boolean {
return try {
val fragment = UserGpxInfoFragment().apply {
arguments = Bundle().apply {
putInt(USER_ID_KEY, userId)
putLong(CHAT_ID_KEY, chatId)
putLong(START_KEY, start)
putLong(END_KEY, end)
}
}
fragment.gpxFile = gpxFile
fragment.show(fm, TAG)
true
} catch (e: RuntimeException) {

View file

@ -9,6 +9,7 @@ import net.osmand.telegram.helpers.LocationMessages.LocationMessage
import net.osmand.telegram.helpers.TelegramHelper
import net.osmand.telegram.helpers.TelegramUiHelper
import net.osmand.util.GeoPointParserUtil
import net.osmand.util.MapUtils
import org.drinkless.td.libcore.telegram.TdApi
import java.io.File
import java.text.SimpleDateFormat
@ -48,7 +49,7 @@ object OsmandLocationUtils {
val content = message.content
return when (content) {
is MessageOsmAndBotLocation -> content.lastUpdated
is MessageUserTextLocation -> content.lastUpdated
is MessageUserLocation -> content.lastUpdated
else -> Math.max(message.editDate, message.date)
}
}
@ -76,49 +77,79 @@ object OsmandLocationUtils {
}
}
fun parseMessage(message: TdApi.Message, helper: TelegramHelper): LocationMessage? {
fun parseUserMapLocation(message: TdApi.Message): MessageUserLocation {
val messageLocation = message.content as TdApi.MessageLocation
return MessageUserLocation().apply {
lat = messageLocation.location.latitude
lon = messageLocation.location.longitude
lastUpdated = getLastUpdatedTime(message)
}
}
fun parseMessage(message: TdApi.Message, helper: TelegramHelper, previousMessage: LocationMessage?): LocationMessage? {
var locationMessage: LocationMessage? = null
val oldContent = message.content
val fromBot = helper.isOsmAndBot(message.senderUserId)
val viaBot = helper.isOsmAndBot(message.viaBotUserId)
var messageType: Int = -1
val parsedMessageContent =
if (oldContent is TdApi.MessageText) {
when {
oldContent.text.text.startsWith(DEVICE_PREFIX) -> {
messageType = LocationMessages.TYPE_BOT_TEXT
parseTextLocation(oldContent.text)
}
oldContent.text.text.startsWith(USER_TEXT_LOCATION_TITLE) -> {
messageType = LocationMessages.TYPE_USER_TEXT
parseTextLocation(oldContent.text, false)
}
else -> null
val messageType = getMessageType(message,helper)
var parsedMessageContent: MessageLocation? = null
if (messageType != -1) {
parsedMessageContent = when (messageType) {
LocationMessages.TYPE_BOT_TEXT -> {
parseTextLocation((oldContent as TdApi.MessageText).text)
}
} else if (oldContent is TdApi.MessageLocation && (fromBot || viaBot)) {
messageType = LocationMessages.TYPE_BOT_MAP
parseOsmAndBotLocation(message)
} else if (oldContent is MessageLocation) {
messageType = 0
oldContent
} else {
null
LocationMessages.TYPE_USER_TEXT -> {
if (oldContent is TdApi.MessageText) {
parseTextLocation(oldContent.text, false)
} else {
oldContent as MessageUserLocation
}
}
LocationMessages.TYPE_BOT_MAP -> {
parseOsmAndBotLocation(message)
}
LocationMessages.TYPE_USER_MAP -> {
parseUserMapLocation(message)
}
else -> null
}
}
if (parsedMessageContent != null) {
val distanceFromPrev = if (previousMessage != null) {
MapUtils.getDistance(previousMessage.lat, previousMessage.lon,
parsedMessageContent.lat, parsedMessageContent.lon)
} else 0.0
locationMessage = LocationMessage(helper.getSenderMessageId(message), message.chatId, parsedMessageContent.lat,
parsedMessageContent.lon, parsedMessageContent.altitude, parsedMessageContent.speed, parsedMessageContent.hdop,
parsedMessageContent.bearing, parsedMessageContent.lastUpdated * 1000L, messageType)
} else if(oldContent is TdApi.MessageLocation){
locationMessage = LocationMessage(helper.getSenderMessageId(message), message.chatId, oldContent.location.latitude,
oldContent.location.longitude, 0.0, 0.0, 0.0,
0.0, getLastUpdatedTime(message) * 1000L, LocationMessages.TYPE_USER_MAP)
parsedMessageContent.bearing, parsedMessageContent.lastUpdated * 1000L, messageType, message.id, distanceFromPrev)
}
return locationMessage
}
fun getMessageType(message: TdApi.Message, helper: TelegramHelper): Int {
val fromBot = helper.isOsmAndBot(message.senderUserId)
val viaBot = helper.isOsmAndBot(message.viaBotUserId)
val oldContent = message.content
return if (oldContent is TdApi.MessageText) {
if (fromBot || viaBot) {
LocationMessages.TYPE_BOT_TEXT
} else {
LocationMessages.TYPE_USER_TEXT
}
} else if (oldContent is TdApi.MessageLocation) {
if (fromBot || viaBot) {
LocationMessages.TYPE_BOT_MAP
} else {
LocationMessages.TYPE_USER_MAP
}
} else if (oldContent is MessageLocation) {
oldContent.type
} else {
-1
}
}
fun formatLocation(sig: Location): String {
return String.format(Locale.US, "%.5f, %.5f", sig.latitude, sig.longitude)
}
@ -148,7 +179,7 @@ object OsmandLocationUtils {
}
fun parseTextLocation(text: TdApi.FormattedText, botLocation: Boolean = true): MessageLocation {
val res = if (botLocation) MessageOsmAndBotLocation() else MessageUserTextLocation()
val res = if (botLocation) MessageOsmAndBotLocation() else MessageUserLocation()
res.type = if (botLocation) LocationMessages.TYPE_BOT_TEXT else LocationMessages.TYPE_USER_TEXT
var locationNA = false
for (s in text.text.lines()) {
@ -460,7 +491,7 @@ object OsmandLocationUtils {
override fun isValid() = name != "" && lat != Double.NaN && lon != Double.NaN
}
class MessageUserTextLocation : MessageLocation() {
class MessageUserLocation : MessageLocation() {
override fun isValid() = lat != Double.NaN && lon != Double.NaN