diff --git a/OsmAnd-telegram/res/layout/my_location_sharing_chat.xml b/OsmAnd-telegram/res/layout/my_location_sharing_chat.xml index baf007cc7c..1d97fe2170 100644 --- a/OsmAnd-telegram/res/layout/my_location_sharing_chat.xml +++ b/OsmAnd-telegram/res/layout/my_location_sharing_chat.xml @@ -107,7 +107,8 @@ - shareInfo.shouldSendViaBotMessage = true + shareInfo.shouldSendViaBotTextMessage = true + shareInfo.shouldSendViaBotMapMessage = true } + prepareForSharingNewMessages() } currentSharingMode = sharingMode } + fun prepareForSharingNewMessages() { + shareChatsInfo.forEach { (_, shareInfo) -> + shareInfo.pendingTdLibText = 0 + shareInfo.pendingTdLibMap = 0 + shareInfo.pendingTextMessage = false + shareInfo.pendingMapMessage = false + } + } + fun getChatLivePeriod(chatId: Long) = shareChatsInfo[chatId]?.livePeriod fun getChatsShareInfo() = shareChatsInfo @@ -211,7 +223,7 @@ class TelegramSettings(private val app: TelegramApplication) { fun getCurrentSharingDevice() = shareDevices.singleOrNull { it.externalId == currentSharingMode } - fun getLastSuccessfulSendTime() = shareChatsInfo.values.maxBy { it.lastSuccessfulSendTimeMs }?.lastSuccessfulSendTimeMs ?: -1 + fun getLastSuccessfulSendTime() = shareChatsInfo.values.maxBy { it.lastSuccessfulSendTime }?.lastSuccessfulSendTime ?: -1 fun stopSharingLocationToChats() { shareChatsInfo.clear() @@ -247,6 +259,7 @@ class TelegramSettings(private val app: TelegramApplication) { fun updateShareInfo(message: TdApi.Message) { val shareInfo = shareChatsInfo[message.chatId] val content = message.content + val isOsmAndBot = app.telegramHelper.isOsmAndBot(message.senderUserId) || app.telegramHelper.isOsmAndBot(message.viaBotUserId) if (shareInfo != null) { when (content) { is TdApi.MessageLocation -> { @@ -256,6 +269,9 @@ class TelegramSettings(private val app: TelegramApplication) { shareInfo.pendingMapMessage = true log.debug("updateShareInfo MAP ${message.id} MessageSendingStatePending") shareInfo.oldMapMessageId = message.id + if (isOsmAndBot) { + shareInfo.shouldSendViaBotMapMessage = false + } } else if (state.constructor == TdApi.MessageSendingStateFailed.CONSTRUCTOR) { shareInfo.hasSharingError = true shareInfo.pendingMapMessage = false @@ -264,12 +280,16 @@ class TelegramSettings(private val app: TelegramApplication) { } else { shareInfo.currentMapMessageId = message.id shareInfo.pendingMapMessage = false - shareInfo.pendingTdLib-- - shareInfo.lastSuccessfulSendTimeMs = Math.max(message.editDate, message.date) * 1000L - if (shareTypeValue == SHARE_TYPE_MAP) { - shareInfo.sentMessages++ + shareInfo.lastSuccessfulSendTime = Math.max(message.editDate, message.date).toLong() + if (!isOsmAndBot) { + shareInfo.pendingTdLibMap-- + if (shareTypeValue == SHARE_TYPE_MAP) { + shareInfo.sentMessages++ + } + } else { + shareInfo.shouldSendViaBotMapMessage = false } - log.debug("updateShareInfo MAP ${message.id} SUCCESS pendingTdLib: ${shareInfo.pendingTdLib}") + log.debug("updateShareInfo MAP ${message.id} SUCCESS pendingTdLibMap: ${shareInfo.pendingTdLibMap}") } } is TdApi.MessageText -> { @@ -279,6 +299,9 @@ class TelegramSettings(private val app: TelegramApplication) { log.debug("updateShareInfo TEXT ${message.id} MessageSendingStatePending") shareInfo.pendingTextMessage = true shareInfo.oldTextMessageId = message.id + if (isOsmAndBot) { + shareInfo.shouldSendViaBotTextMessage = false + } } else if (state.constructor == TdApi.MessageSendingStateFailed.CONSTRUCTOR) { log.debug("updateShareInfo TEXT ${message.id} MessageSendingStateFailed") shareInfo.hasSharingError = true @@ -288,10 +311,14 @@ class TelegramSettings(private val app: TelegramApplication) { 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}") + shareInfo.lastSuccessfulSendTime = Math.max(message.editDate, message.date).toLong() + if (!isOsmAndBot) { + shareInfo.pendingTdLibText-- + shareInfo.sentMessages++ + } else { + shareInfo.shouldSendViaBotTextMessage = false + } + log.debug("updateShareInfo TEXT ${message.id} SUCCESS pendingTdLibMap: ${shareInfo.pendingTdLibText}") } } } @@ -339,7 +366,8 @@ class TelegramSettings(private val app: TelegramApplication) { val currentTime = System.currentTimeMillis() / 1000 val user = app.telegramHelper.getCurrentUser() if (user != null && currentSharingMode != user.id.toString() && shareChatInfo.start == -1L) { - shareChatInfo.shouldSendViaBotMessage = true + shareChatInfo.shouldSendViaBotTextMessage = true + shareChatInfo.shouldSendViaBotMapMessage = true } shareChatInfo.start = currentTime @@ -373,12 +401,14 @@ class TelegramSettings(private val app: TelegramApplication) { var sendChatsErrors = false shareChatsInfo.forEach { (_, shareInfo) -> - if (shareInfo.lastSuccessfulSendTimeMs == -1L && ((statusChangeTime / 1000 - shareInfo.start) < SHARING_INITIALIZATION_TIME)) { + if (shareInfo.lastSuccessfulSendTime == -1L && ((statusChangeTime / 1000 - shareInfo.start) < SHARING_INITIALIZATION_TIME)) { initializing = true - } - if (shareInfo.hasSharingError) { + } else if (shareInfo.hasSharingError + || (shareInfo.lastSuccessfulSendTime - shareInfo.lastSendTextMessageTime > WAITING_TDLIB_TIME) + || (shareInfo.lastSuccessfulSendTime - shareInfo.lastSendMapMessageTime > WAITING_TDLIB_TIME) + ) { sendChatsErrors = true - locationTime = shareInfo.lastSuccessfulSendTimeMs + locationTime = shareInfo.lastSuccessfulSendTime val title = app.telegramHelper.getChat(shareInfo.chatId)?.title if (title != null) { chatsTitles.add(title) @@ -441,11 +471,15 @@ class TelegramSettings(private val app: TelegramApplication) { val currentMapMessageId = shareChatsInfo[chatId]?.currentMapMessageId if (messages.contains(currentMapMessageId)) { shareChatsInfo[chatId]?.currentMapMessageId = -1 + shareChatsInfo[chatId]?.shouldSendViaBotMapMessage = true + shareChatsInfo[chatId]?.shouldSendViaBotTextMessage = true } val currentTextMessageId = shareChatsInfo[chatId]?.currentTextMessageId if (messages.contains(currentTextMessageId)) { shareChatsInfo[chatId]?.currentTextMessageId = -1 shareChatsInfo[chatId]?.updateTextMessageId = 1 + shareChatsInfo[chatId]?.shouldSendViaBotMapMessage = true + shareChatsInfo[chatId]?.shouldSendViaBotTextMessage = true } } @@ -576,7 +610,7 @@ class TelegramSettings(private val app: TelegramApplication) { obj.put(ShareChatInfo.CURRENT_TEXT_MESSAGE_ID_KEY, chatInfo.currentTextMessageId) obj.put(ShareChatInfo.USER_SET_LIVE_PERIOD_KEY, chatInfo.userSetLivePeriod) obj.put(ShareChatInfo.USER_SET_LIVE_PERIOD_START_KEY, chatInfo.userSetLivePeriodStart) - obj.put(ShareChatInfo.LAST_SUCCESSFUL_SEND_TIME_KEY, chatInfo.lastSuccessfulSendTimeMs) + obj.put(ShareChatInfo.LAST_SUCCESSFUL_SEND_TIME_KEY, chatInfo.lastSuccessfulSendTime) obj.put(ShareChatInfo.LAST_SEND_MAP_TIME_KEY, chatInfo.lastSendMapMessageTime) obj.put(ShareChatInfo.LAST_SEND_TEXT_TIME_KEY, chatInfo.lastSendTextMessageTime) obj.put(ShareChatInfo.PENDING_TEXT_MESSAGE_KEY, chatInfo.pendingTextMessage) @@ -605,7 +639,7 @@ class TelegramSettings(private val app: TelegramApplication) { currentTextMessageId = obj.optLong(ShareChatInfo.CURRENT_TEXT_MESSAGE_ID_KEY) userSetLivePeriod = obj.optLong(ShareChatInfo.USER_SET_LIVE_PERIOD_KEY) userSetLivePeriodStart = obj.optLong(ShareChatInfo.USER_SET_LIVE_PERIOD_START_KEY) - lastSuccessfulSendTimeMs = obj.optLong(ShareChatInfo.LAST_SUCCESSFUL_SEND_TIME_KEY) + lastSuccessfulSendTime = obj.optLong(ShareChatInfo.LAST_SUCCESSFUL_SEND_TIME_KEY) lastSendMapMessageTime = obj.optInt(ShareChatInfo.LAST_SEND_MAP_TIME_KEY) lastSendTextMessageTime = obj.optInt(ShareChatInfo.LAST_SEND_TEXT_TIME_KEY) pendingTextMessage = obj.optBoolean(ShareChatInfo.PENDING_TEXT_MESSAGE_KEY) @@ -698,7 +732,8 @@ class TelegramSettings(private val app: TelegramApplication) { val newSharingType = SHARE_TYPE_VALUES[index] if (shareTypeValue != newSharingType && app.telegramHelper.getCurrentUser()?.id.toString() != currentSharingMode) { shareChatsInfo.forEach { (_, shareInfo) -> - shareInfo.shouldSendViaBotMessage = true + shareInfo.shouldSendViaBotTextMessage = true + shareInfo.shouldSendViaBotMapMessage = true } } shareTypeValue = newSharingType @@ -905,19 +940,23 @@ class TelegramSettings(private val app: TelegramApplication) { var oldTextMessageId = -1L var userSetLivePeriod = -1L var userSetLivePeriodStart = -1L - var lastSuccessfulSendTimeMs = -1L + var lastSuccessfulSendTime = -1L var lastSendTextMessageTime = -1 var lastSendMapMessageTime = -1 var sentMessages = 0 - var pendingTdLib = 0 + var pendingTdLibText = 0 + var pendingTdLibMap = 0 var pendingTextMessage = false var pendingMapMessage = false - var shouldSendViaBotMessage = false + var shouldSendViaBotTextMessage = false + var shouldSendViaBotMapMessage = false var hasSharingError = false var shouldDeletePreviousMapMessage = false var shouldDeletePreviousTextMessage = false var additionalActiveTime = ADDITIONAL_ACTIVE_TIME_VALUES_SEC[0] + fun getPendingTdLib() = pendingTdLibText + pendingTdLibMap + fun getNextAdditionalActiveTime(): Long { var index = ADDITIONAL_ACTIVE_TIME_VALUES_SEC.indexOf(additionalActiveTime) return if (ADDITIONAL_ACTIVE_TIME_VALUES_SEC.lastIndex > index) { diff --git a/OsmAnd-telegram/src/net/osmand/telegram/helpers/LocationMessages.kt b/OsmAnd-telegram/src/net/osmand/telegram/helpers/LocationMessages.kt index 421ada72bf..814d56c2d4 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/helpers/LocationMessages.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/helpers/LocationMessages.kt @@ -25,14 +25,27 @@ class LocationMessages(val app: TelegramApplication) { init { dbHelper = SQLiteHelper(app) readBufferedMessages() + readLastMessages() } fun getBufferedMessages(): List { return bufferedMessages.sortedBy { it.time } } + fun getBufferedMessagesCount(): Int { + return bufferedMessages.size + } + + fun getBufferedMessagesCountForChat(chatId: Long, type: Int): Int { + return bufferedMessages.count { it.chatId == chatId && it.type == type } + } + + fun getBufferedMessagesCountForChat(chatId: Long): Int { + return bufferedMessages.count { it.chatId == chatId} + } + fun getBufferedMessagesForChat(chatId: Long): List { - return bufferedMessages.filter { it.chatId==chatId }.sortedBy { it.time } + return bufferedMessages.filter { it.chatId == chatId }.sortedBy { it.time } } fun getIngoingMessages(currentUserId: Int, start: Long, end: Long): List { @@ -43,8 +56,8 @@ class LocationMessages(val app: TelegramApplication) { return dbHelper.getIngoingUserLocations(start, end) } - fun getMessagesForUserInChat(userId: Int, chatId: Long, start: Long, end: Long): List { - return dbHelper.getMessagesForUserInChat(userId, chatId, start, end) + fun getMessagesForUserInChat(userId: Int, chatId: Long, deviceName: String, start: Long, end: Long): List { + return dbHelper.getMessagesForUserInChat(userId, chatId,deviceName, start, end) } fun getMessagesForUser(userId: Int, start: Long, end: Long): List { @@ -61,11 +74,12 @@ class LocationMessages(val app: TelegramApplication) { fun addNewLocationMessage(message: TdApi.Message) { log.debug("addNewLocationMessage ${message.id}") - val type = OsmandLocationUtils.getMessageType(message, app.telegramHelper) - - val newItem = LocationHistoryPoint(message.senderUserId, message.chatId, type) + val type = OsmandLocationUtils.getMessageType(message) + val content = OsmandLocationUtils.parseMessageContent(message, app.telegramHelper) + val deviceName = if (content is OsmandLocationUtils.MessageOsmAndBotLocation) content.deviceName else "" + val newItem = LocationHistoryPoint(message.senderUserId, message.chatId, type, deviceName) val previousMessageLatLon = lastLocationPoints[newItem] - val locationMessage = OsmandLocationUtils.parseMessage(message, app.telegramHelper, previousMessageLatLon) + val locationMessage = OsmandLocationUtils.createLocationMessage(message, app.telegramHelper, content, previousMessageLatLon) if (locationMessage != null) { dbHelper.addLocationMessage(locationMessage) lastLocationPoints[newItem] = LatLon(locationMessage.lat, locationMessage.lon) @@ -75,11 +89,11 @@ class LocationMessages(val app: TelegramApplication) { fun addMyLocationMessage(loc: Location) { log.debug("addMyLocationMessage") val currentUserId = app.telegramHelper.getCurrentUserId() - val newItem = LocationHistoryPoint(currentUserId, 0, -1) + val newItem = LocationHistoryPoint(currentUserId, 0, LocationMessages.TYPE_MY_LOCATION, "") val previousMessageLatLon = lastLocationPoints[newItem] val distance = if (previousMessageLatLon != null) { MapUtils.getDistance(previousMessageLatLon, loc.latitude, loc.longitude) } else 0.0 val message = LocationMessages.LocationMessage(currentUserId, 0, loc.latitude, loc.longitude, loc.altitude, - loc.speed.toDouble(), loc.accuracy.toDouble(), loc.bearing.toDouble(), loc.time, TYPE_MY_LOCATION, 0, distance) + loc.speed.toDouble(), loc.accuracy.toDouble(), loc.bearing.toDouble(), loc.time, TYPE_MY_LOCATION, 0, distance, "") dbHelper.addLocationMessage(message) lastLocationPoints[newItem] = LatLon(message.lat, message.lon) @@ -99,14 +113,6 @@ class LocationMessages(val app: TelegramApplication) { dbHelper.removeBufferedMessage(message) } - fun getBufferedMessagesCount(): Int { - return bufferedMessages.size - } - - fun getBufferedMessagesCountForChat(chatId: Long): Int { - return bufferedMessages.count { it.chatId == chatId } - } - private fun readBufferedMessages() { this.bufferedMessages = dbHelper.getBufferedMessages() } @@ -133,13 +139,13 @@ class LocationMessages(val app: TelegramApplication) { internal fun addBufferedMessage(message: BufferMessage) { writableDatabase?.execSQL(BUFFER_TABLE_INSERT, arrayOf(message.chatId, message.lat, message.lon, message.altitude, message.speed, - message.hdop, message.bearing, message.time, message.type)) + message.hdop, message.bearing, message.time, message.type, message.deviceName)) } 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.messageId, message.distanceFromPrev)) + message.hdop, message.bearing, message.time, message.type, message.messageId, message.distanceFromPrev, message.deviceName)) } internal fun getMessagesForUser(userId: Int, start: Long, end: Long): List { @@ -157,19 +163,6 @@ 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 { val res = arrayListOf() readableDatabase?.rawQuery( @@ -187,42 +180,35 @@ class LocationMessages(val app: TelegramApplication) { internal fun getIngoingUserLocations(start: Long, end: Long): List { val res = arrayListOf() - readableDatabase?.rawQuery( - "$TIMELINE_TABLE_SELECT WHERE $COL_TIME BETWEEN $start AND $end ORDER BY $COL_USER_ID, $COL_CHAT_ID, $COL_TYPE DESC, $COL_TIME ", null - )?.apply { + readableDatabase?.rawQuery("$TIMELINE_TABLE_SELECT WHERE $COL_TIME BETWEEN $start AND $end ORDER BY $COL_USER_ID, $COL_CHAT_ID, $COL_DEVICE_NAME, $COL_TYPE DESC, $COL_TIME ", null)?.apply { if (moveToFirst()) { - var userId = -1 - var chatId = -1L - // TODO query bot name - var botName = "" + var userId: Int + var chatId: Long + var deviceName: String var userLocations: UserLocations? = null var userLocationsMap: MutableMap>? = null - var userLocationsListByType: MutableList? = null var segment: UserTrkSegment? = null do { val locationMessage = readLocationMessage(this@apply) userId = locationMessage.userId chatId = locationMessage.chatId - // TODO compare bot name as well - if(userLocations == null || userLocations.userId != userId || - userLocations.chatId != chatId) { + deviceName = locationMessage.deviceName + if (userLocations == null || userLocations.userId != userId || + userLocations.chatId != chatId || userLocations.deviceName != deviceName) { userLocationsMap = mutableMapOf() - userLocations = UserLocations(userId, chatId, botName, userLocationsMap) + userLocations = UserLocations(userId, chatId, deviceName, userLocationsMap) res.add(userLocations) segment = null } - if(segment == null || - segment.type != locationMessage.type || locationMessage.time - segment.maxTime > 30 * 1000 * 60) { - segment = UserTrkSegment(mutableListOf(), 0.0, locationMessage.type, - locationMessage.time, locationMessage.time) - if(userLocationsMap!![segment.type] == null) { + if (segment == null || segment.type != locationMessage.type || locationMessage.time - segment.maxTime > 30 * 1000 * 60) { + segment = UserTrkSegment(mutableListOf(), 0.0, locationMessage.type, locationMessage.time, locationMessage.time) + if (userLocationsMap!![segment.type] == null) { userLocationsMap[segment.type] = mutableListOf() } userLocationsMap[segment.type]!!.add(segment) } - if(segment.points.size > 0) { - segment.distance += MapUtils.getDistance(locationMessage.lat, - locationMessage.lon, segment.points.last().lat, segment.points.last().lon) + if (segment.points.size > 0) { + segment.distance += MapUtils.getDistance(locationMessage.lat, locationMessage.lon, segment.points.last().lat, segment.points.last().lon) } segment.maxTime = locationMessage.time segment.points.add(locationMessage) @@ -233,11 +219,12 @@ class LocationMessages(val app: TelegramApplication) { return res } - internal fun getMessagesForUserInChat(userId: Int, chatId: Long, start: Long, end: Long): List { + internal fun getMessagesForUserInChat(userId: Int, chatId: Long, deviceName: String, start: Long, end: Long): List { val res = arrayListOf() + val whereDeviceQuery = if (deviceName.isNotEmpty()) "AND $COL_DEVICE_NAME = ?" else "" + val args = if (deviceName.isNotEmpty()) arrayOf(userId.toString(), chatId.toString(), deviceName) else arrayOf(userId.toString(), chatId.toString()) readableDatabase?.rawQuery( - "$TIMELINE_TABLE_SELECT WHERE $COL_USER_ID = ? AND $COL_CHAT_ID = ? AND $COL_TIME BETWEEN $start AND $end ORDER BY $COL_TYPE DESC, $COL_TIME ", - arrayOf(userId.toString(), chatId.toString()))?.apply { + "$TIMELINE_TABLE_SELECT WHERE $COL_USER_ID = ? AND $COL_CHAT_ID = ? $whereDeviceQuery AND $COL_TIME BETWEEN $start AND $end ORDER BY $COL_TYPE DESC, $COL_TIME ", args)?.apply { if (moveToFirst()) { do { res.add(readLocationMessage(this@apply)) @@ -263,10 +250,27 @@ class LocationMessages(val app: TelegramApplication) { internal fun getLastMessages(): MutableMap { val res = mutableMapOf() - readableDatabase?.rawQuery("$TIMELINE_TABLE_SELECT_HISTORY_POINTS ORDER BY $COL_TIME ASC", null)?.apply { + readableDatabase?.rawQuery("$TIMELINE_TABLE_SELECT_HISTORY_POINTS ORDER BY $COL_USER_ID, $COL_CHAT_ID, $COL_TYPE, $COL_DEVICE_NAME, $COL_TIME DESC", null)?.apply { if (moveToFirst()) { + var userId: Int + var chatId: Long + var lat: Double + var lon: Double + var type: Int + var deviceName: String + var locationHistoryPoint: LocationHistoryPoint? = null do { -// res.add(readLocationMessage(this@apply)) + userId = getInt(0) + chatId = getLong(1) + lat = getDouble(2) + lon = getDouble(3) + type = getInt(5) + deviceName = getString(6) + if (locationHistoryPoint == null || locationHistoryPoint.userId != userId + || locationHistoryPoint.chatId != chatId || locationHistoryPoint.deviceName != deviceName) { + locationHistoryPoint = LocationHistoryPoint(userId, chatId, type, deviceName) + res[locationHistoryPoint] = LatLon(lat, lon) + } } while (moveToNext()) } close() @@ -287,8 +291,9 @@ class LocationMessages(val app: TelegramApplication) { val type = cursor.getInt(9) val messageId = cursor.getLong(10) val distanceFromPrev = cursor.getDouble(11) + val botName = cursor.getString(12) - return LocationMessage(userId, chatId, lat, lon, altitude, speed, hdop, bearing, date, type, messageId, distanceFromPrev) + return LocationMessage(userId, chatId, lat, lon, altitude, speed, hdop, bearing, date, type, messageId, distanceFromPrev, botName) } internal fun readBufferMessage(cursor: Cursor): BufferMessage { @@ -301,18 +306,9 @@ class LocationMessages(val app: TelegramApplication) { val bearing = cursor.getDouble(6) val date = cursor.getLong(7) val type = cursor.getInt(8) + val botName = cursor.getString(9) - return BufferMessage(chatId, lat, lon, altitude, speed, hdop, bearing, date, type) - } - - internal fun readLocationHistoryPoint(cursor: Cursor): Pair { - val userId = cursor.getInt(0) - val chatId = cursor.getLong(1) - val lat = cursor.getDouble(2) - val lon = cursor.getDouble(3) - val type = cursor.getInt(4) - - return Pair(LocationHistoryPoint(userId, chatId, type), LatLon(lat, lon)) + return BufferMessage(chatId, lat, lon, altitude, speed, hdop, bearing, date, type, botName) } internal fun clearBufferedMessages() { @@ -332,7 +328,8 @@ class LocationMessages(val app: TelegramApplication) { message.hdop, message.bearing, message.time, - message.type + message.type, + message.deviceName ) ) } @@ -340,7 +337,7 @@ class LocationMessages(val app: TelegramApplication) { companion object { private const val DATABASE_NAME = "location_messages" - private const val DATABASE_VERSION = 5 + private const val DATABASE_VERSION = 6 private const val TIMELINE_TABLE_NAME = "timeline" private const val BUFFER_TABLE_NAME = "buffer" @@ -357,21 +354,22 @@ class LocationMessages(val app: TelegramApplication) { 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 COL_DEVICE_NAME = "device_name" 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, $COL_DISTANCE_FROM_PREV) 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, $COL_DEVICE_NAME) 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, $COL_DISTANCE_FROM_PREV double )") + ("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, $COL_DEVICE_NAME TEXT NOT NULL DEFAULT '')") 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, $COL_DISTANCE_FROM_PREV 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, $COL_DEVICE_NAME FROM $TIMELINE_TABLE_NAME" private const val TIMELINE_TABLE_SELECT_HISTORY_POINTS = - "SELECT $COL_USER_ID, $COL_CHAT_ID, $COL_LAT, $COL_LON, $COL_TIME, $COL_TYPE FROM $TIMELINE_TABLE_NAME" + "SELECT $COL_USER_ID, $COL_CHAT_ID, $COL_LAT, $COL_LON, $COL_TIME, $COL_TYPE, $COL_DEVICE_NAME FROM $TIMELINE_TABLE_NAME" private const val TIMELINE_TABLE_CLEAR = "DELETE FROM $TIMELINE_TABLE_NAME" @@ -379,17 +377,17 @@ class LocationMessages(val app: TelegramApplication) { // Buffer messages table private const val BUFFER_TABLE_INSERT = - ("INSERT INTO $BUFFER_TABLE_NAME ($COL_CHAT_ID, $COL_LAT, $COL_LON, $COL_ALTITUDE, $COL_SPEED, $COL_HDOP, $COL_BEARING, $COL_TIME, $COL_TYPE) 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_DEVICE_NAME) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") private const val BUFFER_TABLE_CREATE = - ("CREATE TABLE IF NOT EXISTS $BUFFER_TABLE_NAME ($COL_CHAT_ID long, $COL_LAT double, $COL_LON double, $COL_ALTITUDE double, $COL_SPEED float, $COL_HDOP double, $COL_BEARING double, $COL_TIME long, $COL_TYPE int)") + ("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_DEVICE_NAME TEXT NOT NULL DEFAULT '')") private const val BUFFER_TABLE_SELECT = - "SELECT $COL_CHAT_ID, $COL_LAT, $COL_LON, $COL_ALTITUDE, $COL_SPEED, $COL_HDOP, $COL_BEARING, $COL_TIME, $COL_TYPE FROM $BUFFER_TABLE_NAME" + "SELECT $COL_CHAT_ID, $COL_LAT, $COL_LON, $COL_ALTITUDE, $COL_SPEED, $COL_HDOP, $COL_BEARING, $COL_TIME, $COL_TYPE, $COL_DEVICE_NAME FROM $BUFFER_TABLE_NAME" private const val BUFFER_TABLE_CLEAR = "DELETE FROM $BUFFER_TABLE_NAME" - private const val BUFFER_TABLE_REMOVE = "DELETE FROM $BUFFER_TABLE_NAME WHERE $COL_CHAT_ID = ? AND $COL_LAT = ? AND $COL_LON = ? AND $COL_ALTITUDE = ? AND $COL_SPEED = ? AND $COL_HDOP = ? AND $COL_BEARING = ? AND $COL_TIME = ? AND $COL_TYPE = ?" + private const val BUFFER_TABLE_REMOVE = "DELETE FROM $BUFFER_TABLE_NAME WHERE $COL_CHAT_ID = ? AND $COL_LAT = ? AND $COL_LON = ? AND $COL_ALTITUDE = ? AND $COL_SPEED = ? AND $COL_HDOP = ? AND $COL_BEARING = ? AND $COL_TIME = ? AND $COL_TYPE = ? AND $COL_DEVICE_NAME = ?" private const val BUFFER_TABLE_DELETE = "DROP TABLE IF EXISTS $BUFFER_TABLE_NAME" } @@ -407,7 +405,8 @@ class LocationMessages(val app: TelegramApplication) { val time: Long, val type: Int, val messageId: Long, - val distanceFromPrev: Double) + val distanceFromPrev: Double, + val deviceName: String) data class BufferMessage ( val chatId: Long, @@ -418,32 +417,30 @@ class LocationMessages(val app: TelegramApplication) { val hdop: Double, val bearing: Double, val time: Long, - val type: Int) + val type: Int, + val deviceName: String) data class UserLocations( - var userId: Int, - var chatId: Long, - var botName: String, - var locationsByType: Map> - - - ){ + val userId: Int, + val chatId: Long, + val deviceName: String, + val locationsByType: Map> + ) { fun getUniqueSegments(): List { - // TODO TYPE_BOT_MAP. TYPE_BOT_TEXT, TYPE_USER_BOTH, TYPE_BOT_BOTH - delete val list = mutableListOf() - if(locationsByType.containsKey(TYPE_MY_LOCATION)) { - return locationsByType.get(TYPE_MY_LOCATION)?: list + if (locationsByType.containsKey(TYPE_MY_LOCATION)) { + return locationsByType[TYPE_MY_LOCATION] ?: list } - list.addAll(locationsByType.get(TYPE_USER_TEXT)?: emptyList()) - val mapList = locationsByType.get(TYPE_USER_MAP)?: emptyList(); + list.addAll(locationsByType[TYPE_TEXT] ?: emptyList()) + val mapList = locationsByType[TYPE_MAP] ?: emptyList() mapList.forEach { - var ti = 0; - while(ti < list.size && list[ti].maxTime < it.minTime) { - ti++; + var ti = 0 + while (ti < list.size && list[ti].maxTime < it.minTime) { + ti++ } - if(ti < list.size && list[ti].minTime > it.maxTime ) { + if (ti < list.size && list[ti].minTime > it.maxTime) { list.add(ti, it) - } else if(ti == list.size) { + } else if (ti == list.size) { list.add(it) } } @@ -461,25 +458,23 @@ class LocationMessages(val app: TelegramApplication) { var maxTime: Long ) { fun newer(other: UserTrkSegment): Boolean { - return other.maxTime < maxTime; + return other.maxTime < maxTime } - fun overlap(other: UserTrkSegment): Boolean { - - if(other.maxTime < maxTime) { - return other.maxTime > minTime; + return if (other.maxTime < maxTime) { + other.maxTime > minTime } else { - return other.minTime < maxTime; + other.minTime < maxTime } } - } data class LocationHistoryPoint( val userId: Int, val chatId: Long, - val type: Int + val type: Int, + val deviceName: String ) { override fun equals(other: Any?): Boolean { @@ -490,7 +485,7 @@ class LocationMessages(val app: TelegramApplication) { return false } val o = other as LocationHistoryPoint? - return this.userId == o!!.userId && this.chatId == o.chatId && this.type == o.type + return this.userId == o!!.userId && this.chatId == o.chatId && this.type == o.type && this.deviceName == o.deviceName } override fun hashCode(): Int { @@ -499,6 +494,7 @@ class LocationMessages(val app: TelegramApplication) { result = prime * result + userId.hashCode() result = prime * result + chatId.hashCode() result = prime * result + type.hashCode() + result = prime * result + deviceName.hashCode() return result } } @@ -506,12 +502,8 @@ class LocationMessages(val app: TelegramApplication) { companion object { - const val TYPE_USER_MAP = 0 - const val TYPE_USER_TEXT = 1 - const val TYPE_USER_BOTH = 2 - const val TYPE_BOT_MAP = 3 - const val TYPE_BOT_TEXT = 4 - const val TYPE_BOT_BOTH = 5 - const val TYPE_MY_LOCATION = 6 + const val TYPE_MAP = 0 + const val TYPE_TEXT = 1 + const val TYPE_MY_LOCATION = 3 } -} +} \ No newline at end of file diff --git a/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShareLocationHelper.kt b/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShareLocationHelper.kt index 74dbec35be..65643cb369 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShareLocationHelper.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShareLocationHelper.kt @@ -97,31 +97,44 @@ class ShareLocationHelper(private val app: TelegramApplication) { } } + fun checkAndSendBufferMessages() { + log.debug("checkAndSendBufferMessages") + var bufferedMessagesFull = false + app.settings.getChatsShareInfo().forEach { (chatId, shareInfo) -> + checkAndSendBufferMessagesToChat(chatId) + if (shareInfo.getPendingTdLib() > 10) { + bufferedMessagesFull = true + } + } + if (bufferedMessagesFull) { + checkNetworkType() + } + } + fun checkAndSendBufferMessagesToChat(chatId: Long) { val shareInfo = app.settings.getChatsShareInfo()[chatId] - if (shareInfo != null && shareInfo.pendingTdLib < 10) { - 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) - } else if (it.type == LocationMessages.TYPE_USER_MAP && !shareInfo.pendingMapMessage && shareInfo.currentMapMessageId != -1L) { - app.telegramHelper.editMapLocation(shareInfo, it) - app.locationMessages.removeBufferedMessage(it) - } else if (it.type == LocationMessages.TYPE_USER_BOTH) { - var messageSent = false - if (!shareInfo.pendingMapMessage && shareInfo.currentMapMessageId != -1L) { - app.telegramHelper.editMapLocation(shareInfo, it) - messageSent = true + if (shareInfo != null && shareInfo.getPendingTdLib() < 10) { + app.locationMessages.getBufferedMessagesForChat(chatId).forEach { + if (it.type == LocationMessages.TYPE_TEXT) { + if (it.deviceName.isEmpty()) { + if (!shareInfo.pendingTextMessage && shareInfo.currentTextMessageId != -1L) { + app.telegramHelper.editTextLocation(shareInfo, it) + app.locationMessages.removeBufferedMessage(it) + } + } else { + sendLocationToBot(it, shareInfo, SHARE_TYPE_TEXT) } - if (!shareInfo.pendingTextMessage && shareInfo.currentTextMessageId != -1L) { - app.telegramHelper.editTextLocation(shareInfo, it) - messageSent = true - } - if (messageSent) { - app.locationMessages.removeBufferedMessage(it) + } else if (it.type == LocationMessages.TYPE_MAP) { + if (it.deviceName.isEmpty()) { + if (!shareInfo.pendingMapMessage && shareInfo.currentMapMessageId != -1L) { + app.telegramHelper.editMapLocation(shareInfo, it) + app.locationMessages.removeBufferedMessage(it) + } + } else { + sendLocationToBot(it, shareInfo, SHARE_TYPE_MAP) } } - if (shareInfo.pendingTdLib >= 10) { + if (shareInfo.getPendingTdLib() >= 10) { return } } @@ -166,25 +179,6 @@ class ShareLocationHelper(private val app: TelegramApplication) { refreshNotification() } - private fun checkAndSendBufferMessages(){ - log.debug("checkAndSendBufferMessages") - app.settings.getChatsShareInfo().forEach loop@{ (chatId, shareInfo) -> - if (shareInfo.pendingTdLib < 10) { - 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) - } else if (it.type == LocationMessages.TYPE_USER_MAP && !shareInfo.pendingMapMessage && shareInfo.currentMapMessageId != -1L) { - app.telegramHelper.editMapLocation(shareInfo, it) - app.locationMessages.removeBufferedMessage(it) - } - if (shareInfo.pendingTdLib >= 10) { - return@loop - } - } - } - } - } private fun shareLocationMessages(location: Location, userId: Int) { val chatsShareInfo = app.settings.getChatsShareInfo() @@ -195,32 +189,29 @@ class ShareLocationHelper(private val app: TelegramApplication) { val accuracy = location.accuracy.toDouble() val bearing = location.bearing.toDouble() val time = location.time - val sharingMode = app.settings.currentSharingMode - val isBot = sharingMode != userId.toString() + val isBot = app.settings.currentSharingMode != userId.toString() + val deviceName = if (isBot) app.settings.currentSharingMode else "" var bufferedMessagesFull = false - val type = when (app.settings.shareTypeValue) { - SHARE_TYPE_MAP -> { - if (isBot) LocationMessages.TYPE_BOT_MAP else LocationMessages.TYPE_USER_MAP - } - SHARE_TYPE_TEXT -> { - if (isBot) LocationMessages.TYPE_BOT_TEXT else LocationMessages.TYPE_USER_TEXT - } - SHARE_TYPE_MAP_AND_TEXT -> { - if (isBot) LocationMessages.TYPE_BOT_BOTH else LocationMessages.TYPE_USER_BOTH - } else -> -1 - } + chatsShareInfo.values.forEach { shareInfo -> - if (shareInfo.pendingTdLib >= 10) { + if (shareInfo.getPendingTdLib() >= 10 || app.locationMessages.getBufferedMessagesCountForChat(shareInfo.chatId) >= 10) { bufferedMessagesFull = true } - val message = BufferMessage(shareInfo.chatId, latitude, longitude, altitude, speed, accuracy, bearing, time, type) - - if (type == LocationMessages.TYPE_USER_MAP || type == LocationMessages.TYPE_BOT_MAP) { - prepareMapMessage(shareInfo, message, isBot, sharingMode) - } else if (type == LocationMessages.TYPE_USER_TEXT || type == LocationMessages.TYPE_BOT_TEXT) { - prepareTextMessage(shareInfo, message, isBot, sharingMode) - } else if (type == LocationMessages.TYPE_USER_BOTH || type == LocationMessages.TYPE_BOT_BOTH) { - prepareMapAndTextMessage(shareInfo, message, isBot, sharingMode) + when (app.settings.shareTypeValue) { + SHARE_TYPE_MAP -> { + val message = BufferMessage(shareInfo.chatId, latitude, longitude, altitude, speed, accuracy, bearing, time, LocationMessages.TYPE_MAP, deviceName) + prepareMapMessage(shareInfo, message, isBot) + } + SHARE_TYPE_TEXT -> { + val message = BufferMessage(shareInfo.chatId, latitude, longitude, altitude, speed, accuracy, bearing, time, LocationMessages.TYPE_TEXT, deviceName) + prepareTextMessage(shareInfo, message, isBot) + } + SHARE_TYPE_MAP_AND_TEXT -> { + val messageMap = BufferMessage(shareInfo.chatId, latitude, longitude, altitude, speed, accuracy, bearing, time, LocationMessages.TYPE_MAP, deviceName) + val messageText = BufferMessage(shareInfo.chatId, latitude, longitude, altitude, speed, accuracy, bearing, time, LocationMessages.TYPE_TEXT, deviceName) + prepareMapMessage(shareInfo, messageMap, isBot) + prepareTextMessage(shareInfo, messageText, isBot) + } } } app.locationMessages.addMyLocationMessage(location) @@ -229,23 +220,27 @@ class ShareLocationHelper(private val app: TelegramApplication) { } } - private fun prepareTextMessage(shareInfo: TelegramSettings.ShareChatInfo,message: BufferMessage,isBot:Boolean, sharingMode: String) { + private fun prepareTextMessage(shareInfo: TelegramSettings.ShareChatInfo, message: BufferMessage, isBot: Boolean) { log.debug("prepareTextMessage $message") if (shareInfo.currentTextMessageId == -1L) { if (shareInfo.pendingTextMessage) { app.locationMessages.addBufferedMessage(message) } else { if (isBot) { - sendLocationToBot(message, sharingMode, shareInfo, SHARE_TYPE_TEXT) + sendLocationToBot(message, shareInfo, SHARE_TYPE_TEXT) } else { app.telegramHelper.sendNewTextLocation(shareInfo, message) } } } else { if (isBot) { - sendLocationToBot(message, sharingMode, shareInfo, SHARE_TYPE_TEXT) + if (app.isInternetConnectionAvailable) { + sendLocationToBot(message, shareInfo, SHARE_TYPE_TEXT) + } else { + app.locationMessages.addBufferedMessage(message) + } } else { - if (shareInfo.pendingTdLib < 10) { + if (shareInfo.getPendingTdLib() < 10) { app.telegramHelper.editTextLocation(shareInfo, message) } else { app.locationMessages.addBufferedMessage(message) @@ -254,48 +249,34 @@ class ShareLocationHelper(private val app: TelegramApplication) { } } - private fun prepareMapMessage(shareInfo: TelegramSettings.ShareChatInfo,message: BufferMessage,isBot:Boolean, sharingMode: String) { + private fun prepareMapMessage(shareInfo: TelegramSettings.ShareChatInfo, message: BufferMessage, isBot: Boolean) { log.debug("prepareMapMessage $message") if (shareInfo.currentMapMessageId == -1L) { if (shareInfo.pendingMapMessage) { app.locationMessages.addBufferedMessage(message) } else { if (isBot) { - sendLocationToBot(message, sharingMode, shareInfo, SHARE_TYPE_MAP) + if (app.isInternetConnectionAvailable) { + sendLocationToBot(message, shareInfo, SHARE_TYPE_MAP) + } else { + app.locationMessages.addBufferedMessage(message) + } } else { app.telegramHelper.sendNewMapLocation(shareInfo, message) } } } else { if (isBot) { - sendLocationToBot(message, sharingMode, shareInfo, SHARE_TYPE_MAP) - } else { - if (shareInfo.pendingTdLib < 10) { - app.telegramHelper.editMapLocation(shareInfo, message) + if (app.isInternetConnectionAvailable) { + sendLocationToBot(message, shareInfo, SHARE_TYPE_MAP) } else { app.locationMessages.addBufferedMessage(message) } - } - } - } - - private fun prepareMapAndTextMessage(shareInfo: TelegramSettings.ShareChatInfo, message: BufferMessage, isBot:Boolean, sharingMode: String) { - log.debug("prepareMapAndTextMessage $message") - if (shareInfo.pendingMapMessage || shareInfo.pendingTextMessage || shareInfo.pendingTdLib >= 10) { - app.locationMessages.addBufferedMessage(message) - } else { - if (isBot) { - sendLocationToBot(message, sharingMode, shareInfo, SHARE_TYPE_MAP_AND_TEXT) } else { - if (shareInfo.currentMapMessageId == -1L) { - app.telegramHelper.sendNewMapLocation(shareInfo, message) - } else { + if (shareInfo.getPendingTdLib() < 10) { app.telegramHelper.editMapLocation(shareInfo, message) - } - if (shareInfo.currentTextMessageId == -1L) { - app.telegramHelper.sendNewTextLocation(shareInfo, message) } else { - app.telegramHelper.editTextLocation(shareInfo, message) + app.locationMessages.addBufferedMessage(message) } } } @@ -312,10 +293,12 @@ class ShareLocationHelper(private val app: TelegramApplication) { } } - private fun sendLocationToBot(locationMessage: BufferMessage, sharingMode: String, shareInfo: TelegramSettings.ShareChatInfo, shareType: String) { + private fun sendLocationToBot(locationMessage: BufferMessage, shareInfo: TelegramSettings.ShareChatInfo, shareType: String) { if (app.isInternetConnectionAvailable) { - log.debug("sendLocationToBot $locationMessage") - val url = getDeviceSharingUrl(locationMessage, sharingMode) + log.debug("sendLocationToBot ${locationMessage.deviceName}") + val url = getDeviceSharingUrl(locationMessage, locationMessage.deviceName) + shareInfo.lastSendTextMessageTime = (System.currentTimeMillis() / 1000).toInt() + shareInfo.lastSendTextMessageTime = (System.currentTimeMillis() / 1000).toInt() AndroidNetworkUtils.sendRequestAsync(app, url, null, "Send Location", false, false, object : AndroidNetworkUtils.OnRequestResultListener { override fun onResult(result: String?) { @@ -323,10 +306,15 @@ class ShareLocationHelper(private val app: TelegramApplication) { val success = checkResultAndUpdateShareInfoSuccessfulSendTime(result, chatsShareInfo) val osmandBotId = app.telegramHelper.getOsmandBot()?.id ?: -1 val device = app.settings.getCurrentSharingDevice() - - if (success && shareInfo.shouldSendViaBotMessage && osmandBotId != -1 && device != null) { - app.telegramHelper.sendViaBotLocationMessage(osmandBotId, shareInfo, TdApi.Location(locationMessage.lat, locationMessage.lon), device, shareType) - shareInfo.shouldSendViaBotMessage = false + if (success) { + shareInfo.sentMessages++ + shareInfo.lastSuccessfulSendTime = System.currentTimeMillis() / 1000 + app.locationMessages.removeBufferedMessage(locationMessage) + if ((shareInfo.shouldSendViaBotTextMessage || shareInfo.shouldSendViaBotMapMessage) && osmandBotId != -1 && device != null) { + app.telegramHelper.sendViaBotLocationMessage(osmandBotId, shareInfo, TdApi.Location(locationMessage.lat, locationMessage.lon), device, shareType) + shareInfo.shouldSendViaBotTextMessage = false + shareInfo.shouldSendViaBotMapMessage = false + } } } }) @@ -356,10 +344,10 @@ class ShareLocationHelper(private val app: TelegramApplication) { try { val jsonResult = JSONObject(result) val status = jsonResult.getString("status") - val currentTime = System.currentTimeMillis() + val currentTime = System.currentTimeMillis() / 1000 if (status == "OK") { chatsShareInfo.forEach { (_, shareInfo) -> - shareInfo.lastSuccessfulSendTimeMs = currentTime + shareInfo.lastSuccessfulSendTime = currentTime } return true } diff --git a/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShowLocationHelper.kt b/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShowLocationHelper.kt index d36e899557..1f05580062 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShowLocationHelper.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShowLocationHelper.kt @@ -119,7 +119,7 @@ class ShowLocationHelper(private val app: TelegramApplication) { } } } else if (chatTitle != null && content is MessageOsmAndBotLocation && content.isValid()) { - val name = content.name + val name = content.deviceName setupMapLayer() if (update) { osmandAidlHelper.updateMapPoint(MAP_LAYER_ID, "${chatId}_$name", name, name, @@ -186,12 +186,19 @@ class ShowLocationHelper(private val app: TelegramApplication) { osmandAidlHelper.unregisterFromUpdates() } app.startUserLocationService() + showingLocation = true } else { - if (isUseOsmandCallback()) { + showingLocation = if (isUseOsmandCallback()) { app.stopUserLocationService() osmandAidlHelper.registerForUpdates() } else { - app.startUserLocationService() + if (app.settings.hasAnyChatToShowOnMap()) { + app.startUserLocationService() + true + } else { + app.stopUserLocationService() + false + } } } } @@ -272,7 +279,7 @@ class ShowLocationHelper(private val app: TelegramApplication) { 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}") + osmandAidlHelper.removeMapPoint(MAP_LAYER_ID, "${chatId}_${content.deviceName}") } } } \ No newline at end of file diff --git a/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramHelper.kt b/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramHelper.kt index a6e23f6f03..a45a08bac4 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramHelper.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramHelper.kt @@ -2,19 +2,16 @@ package net.osmand.telegram.helpers import android.text.TextUtils import net.osmand.PlatformUtil -import net.osmand.telegram.* +import net.osmand.telegram.SHARE_TYPE_MAP +import net.osmand.telegram.SHARE_TYPE_MAP_AND_TEXT +import net.osmand.telegram.SHARE_TYPE_TEXT +import net.osmand.telegram.TelegramSettings import net.osmand.telegram.helpers.TelegramHelper.TelegramAuthenticationParameterType.* import net.osmand.telegram.utils.GRAYSCALE_PHOTOS_DIR 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.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 -import net.osmand.telegram.utils.OsmandLocationUtils.parseOsmAndBotLocationContent -import net.osmand.telegram.utils.OsmandLocationUtils.parseTextLocation import org.drinkless.td.libcore.telegram.Client import org.drinkless.td.libcore.telegram.Client.ResultHandler import org.drinkless.td.libcore.telegram.TdApi @@ -44,8 +41,6 @@ class TelegramHelper private constructor() { const val MAX_LOCATION_MESSAGE_HISTORY_SCAN_SEC = 60 * 60 * 24 // one day - const val SEND_NEW_MESSAGE_INTERVAL_SEC = 10 * 60 // 10 minutes - private var helper: TelegramHelper? = null val instance: TelegramHelper @@ -161,7 +156,7 @@ class TelegramHelper private constructor() { fun getMessagesByChatIds(messageExpTime: Long): Map> { val res = mutableMapOf>() for (message in usersLocationMessages.values) { - if (System.currentTimeMillis() / 1000 - getLastUpdatedTime(message) < messageExpTime) { + if (System.currentTimeMillis() / 1000 - OsmandLocationUtils.getLastUpdatedTime(message) < messageExpTime) { var messages = res[message.chatId] if (messages != null) { messages.add(message) @@ -343,19 +338,6 @@ class TelegramHelper private constructor() { else -> null } - fun getOsmAndBotDeviceName(message: TdApi.Message): String { - var deviceName = "" - if (message.replyMarkup is TdApi.ReplyMarkupInlineKeyboard) { - val replyMarkup = message.replyMarkup as TdApi.ReplyMarkupInlineKeyboard - try { - deviceName = replyMarkup.rows[0][1].text.split("\\s".toRegex())[1] - } catch (e: Exception) { - - } - } - return deviceName - } - fun getUserIdFromChatType(type: TdApi.ChatType) = when (type) { is TdApi.ChatTypePrivate -> type.userId is TdApi.ChatTypeSecret -> type.userId @@ -394,11 +376,6 @@ class TelegramHelper private constructor() { return File("$appDir/$GRAYSCALE_PHOTOS_DIR$userId$GRAYSCALE_PHOTOS_EXT").exists() } - private fun isUserLocationMessage(message: TdApi.Message): Boolean { - val cont = message.content - return (cont is MessageUserLocation || cont is TdApi.MessageLocation) - } - private fun hasLocalUserPhoto(user: TdApi.User): Boolean { val localPhoto = user.profilePhoto?.small?.local return if (localPhoto != null) { @@ -506,7 +483,8 @@ class TelegramHelper private constructor() { if (error.code != IGNORED_ERROR_CODE) { listener?.onTelegramError(error.code, error.message) } else { - shareInfo.shouldSendViaBotMessage = true + shareInfo.shouldSendViaBotTextMessage = true + shareInfo.shouldSendViaBotMapMessage = true } } TdApi.InlineQueryResults.CONSTRUCTOR -> { @@ -699,30 +677,31 @@ 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) - val oldContent = message.content - if (oldContent is TdApi.MessageText) { - if (oldContent.text.text.startsWith(DEVICE_PREFIX)) { - message.content = parseTextLocation(oldContent.text) - } else if (oldContent.text.text.startsWith(USER_TEXT_LOCATION_TITLE)) { - message.content = parseTextLocation(oldContent.text, false) - } - } else if (oldContent is TdApi.MessageLocation && (fromBot || viaBot)) { - message.content = parseOsmAndBotLocation(message) + if (message.isOutgoing && !fromBot && !viaBot) { + return } removeOldMessages(message, fromBot, viaBot) - val oldMessage = usersLocationMessages.values.firstOrNull { getSenderMessageId(it) == getSenderMessageId(message) && !fromBot && !viaBot } + val oldMessage = usersLocationMessages.values.firstOrNull { + getSenderMessageId(it) == getSenderMessageId(message) && it.chatId == message.chatId + && OsmandLocationUtils.getOsmAndBotDeviceName(it) == OsmandLocationUtils.getOsmAndBotDeviceName(message) + } 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) { + if (message.isOutgoing) { + if (fromBot||viaBot) { + outgoingMessagesListeners.forEach { + it.onUpdateMessages(listOf(message)) + } + } else { + return + } + } else { + incomingMessagesListeners.forEach { it.onReceiveChatLocationMessages(message.chatId, message) } } @@ -738,16 +717,13 @@ class TelegramHelper private constructor() { val viaSameBot = newMessage.viaBotUserId == message.viaBotUserId if (fromBot || viaBot) { if ((fromBot && sameSender) || (viaBot && viaSameBot)) { - val newCont = newMessage.content - val cont = message.content - if (newCont is MessageOsmAndBotLocation && cont is MessageOsmAndBotLocation) { - if (newCont.name == cont.name) { - iterator.remove() - } + val newDeviceName = OsmandLocationUtils.getOsmAndBotDeviceName(newMessage) + val contDeviceName = OsmandLocationUtils.getOsmAndBotDeviceName(newMessage) + if (newDeviceName == contDeviceName) { + iterator.remove() } } - } else if (sameSender && isUserLocationMessage(message) && isUserLocationMessage(newMessage) - && Math.max(newMessage.editDate, newMessage.date) >= Math.max(message.editDate, message.date)) { + } else if (sameSender && Math.max(newMessage.editDate, newMessage.date) >= Math.max(message.editDate, message.date)) { iterator.remove() } } @@ -756,6 +732,7 @@ class TelegramHelper private constructor() { fun stopSendingLiveLocationToChat(shareInfo: TelegramSettings.ShareChatInfo) { if (shareInfo.currentMapMessageId != -1L && shareInfo.chatId != -1L) { + shareInfo.lastSendMapMessageTime = (System.currentTimeMillis() / 1000).toInt() client?.send( TdApi.EditMessageLiveLocation(shareInfo.chatId, shareInfo.currentMapMessageId, null, null)) { obj -> handleMapLocationMessageUpdate(obj, shareInfo) @@ -833,6 +810,11 @@ class TelegramHelper private constructor() { private fun sendNewLiveLocationMessage(shareInfo: TelegramSettings.ShareChatInfo, content: TdApi.InputMessageContent) { needRefreshActiveLiveLocationMessages = true log.debug("sendNewLiveLocationMessage") + if (content is TdApi.InputMessageText) { + shareInfo.lastSendTextMessageTime = (System.currentTimeMillis() / 1000).toInt() + } else if (content is TdApi.InputMessageLocation) { + shareInfo.lastSendMapMessageTime = (System.currentTimeMillis() / 1000).toInt() + } client?.send(TdApi.SendMessage(shareInfo.chatId, 0, false, true, null, content)) { obj -> if (content is TdApi.InputMessageText) { handleTextLocationMessageUpdate(obj, shareInfo) @@ -847,8 +829,9 @@ class TelegramHelper private constructor() { val content = OsmandLocationUtils.getTextMessageContent(shareInfo.updateTextMessageId, location) if (!shareInfo.pendingTextMessage) { shareInfo.pendingTextMessage = true - shareInfo.pendingTdLib++ - log.error("sendNewTextLocation ${shareInfo.pendingTdLib}") + shareInfo.pendingTdLibText++ + shareInfo.lastSendTextMessageTime = (System.currentTimeMillis() / 1000).toInt() + log.error("sendNewTextLocation ${shareInfo.pendingTdLibText}") client?.send(TdApi.SendMessage(shareInfo.chatId, 0, false, true, null, content)) { obj -> handleTextLocationMessageUpdate(obj, shareInfo) } @@ -858,8 +841,9 @@ class TelegramHelper private constructor() { fun editTextLocation(shareInfo: TelegramSettings.ShareChatInfo, location: LocationMessages.BufferMessage) { val content = OsmandLocationUtils.getTextMessageContent(shareInfo.updateTextMessageId, location) if (shareInfo.currentTextMessageId!=-1L) { - shareInfo.pendingTdLib++ - log.info("editTextLocation ${shareInfo.currentTextMessageId} pendingTdLib: ${shareInfo.pendingTdLib}") + shareInfo.pendingTdLibText++ + shareInfo.lastSendTextMessageTime = (System.currentTimeMillis() / 1000).toInt() + log.info("editTextLocation ${shareInfo.currentTextMessageId} pendingTdLibText: ${shareInfo.pendingTdLibText}") client?.send(TdApi.EditMessageText(shareInfo.chatId, shareInfo.currentTextMessageId, null, content)) { obj -> handleTextLocationMessageUpdate(obj, shareInfo) } @@ -878,8 +862,9 @@ class TelegramHelper private constructor() { val content = TdApi.InputMessageLocation(location, livePeriod) if (!shareInfo.pendingMapMessage) { shareInfo.pendingMapMessage = true - shareInfo.pendingTdLib++ - log.error("sendNewMapLocation ${shareInfo.pendingTdLib}") + shareInfo.pendingTdLibMap++ + shareInfo.lastSendMapMessageTime = (System.currentTimeMillis() / 1000).toInt() + log.error("sendNewMapLocation ${shareInfo.pendingTdLibMap}") client?.send(TdApi.SendMessage(shareInfo.chatId, 0, false, true, null, content)) { obj -> handleMapLocationMessageUpdate(obj, shareInfo) } @@ -890,8 +875,9 @@ class TelegramHelper private constructor() { needRefreshActiveLiveLocationMessages = true val location = TdApi.Location(locationMessage.lat, locationMessage.lon) if (shareInfo.currentMapMessageId!=-1L) { - shareInfo.pendingTdLib++ - log.info("editMapLocation ${shareInfo.currentMapMessageId} pendingTdLib: ${shareInfo.pendingTdLib}") + shareInfo.pendingTdLibMap++ + shareInfo.lastSendMapMessageTime = (System.currentTimeMillis() / 1000).toInt() + log.info("editMapLocation ${shareInfo.currentMapMessageId} pendingTdLibMap: ${shareInfo.pendingTdLibMap}") client?.send(TdApi.EditMessageLiveLocation(shareInfo.chatId, shareInfo.currentMapMessageId, null, location)) { obj -> handleMapLocationMessageUpdate(obj, shareInfo) } @@ -927,7 +913,6 @@ class TelegramHelper private constructor() { } obj.sendingState?.constructor == TdApi.MessageSendingStatePending.CONSTRUCTOR -> { shareInfo.pendingMapMessage = true - shareInfo.lastSendMapMessageTime = obj.date log.debug("handleMapLocationMessageUpdate - MessageSendingStatePending") outgoingMessagesListeners.forEach { it.onUpdateMessages(listOf(obj)) @@ -975,7 +960,6 @@ class TelegramHelper private constructor() { } obj.sendingState?.constructor == TdApi.MessageSendingStatePending.CONSTRUCTOR -> { shareInfo.pendingTextMessage = true - shareInfo.lastSendTextMessageTime = obj.date log.debug("handleTextLocationMessageUpdate - MessageSendingStatePending") outgoingMessagesListeners.forEach { it.onUpdateMessages(listOf(obj)) @@ -1324,20 +1308,7 @@ class TelegramHelper private constructor() { } else { synchronized(message) { lastTelegramUpdateTime = Math.max(lastTelegramUpdateTime, Math.max(message.date, message.editDate)) - val newContent = updateMessageContent.newContent - val fromBot = isOsmAndBot(message.senderUserId) - val viaBot = isOsmAndBot(message.viaBotUserId) - message.content = if (newContent is TdApi.MessageText) { - parseTextLocation(newContent.text, (fromBot || viaBot)) - } else if (newContent is TdApi.MessageLocation) { - if(fromBot||viaBot){ - parseOsmAndBotLocationContent(message.content as MessageOsmAndBotLocation, newContent) - } else { - OsmandLocationUtils.parseUserMapLocation(message) - } - } else { - newContent - } + message.content = updateMessageContent.newContent } incomingMessagesListeners.forEach { it.onReceiveChatLocationMessages(message.chatId, message) diff --git a/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramUiHelper.kt b/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramUiHelper.kt index 4b846dc88d..e472bc0a6f 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramUiHelper.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramUiHelper.kt @@ -6,7 +6,6 @@ import android.widget.ImageView import net.osmand.data.LatLon import net.osmand.telegram.R import net.osmand.telegram.TelegramApplication -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 @@ -67,7 +66,7 @@ object TelegramUiHelper { val message = messages.firstOrNull { it.viaBotUserId == 0 } if (message != null) { res.lastUpdated = OsmandLocationUtils.getLastUpdatedTime(message) - val content = message.content + val content = OsmandLocationUtils.parseMessageContent(message, helper) if (content is TdApi.MessageLocation) { res.latLon = LatLon(content.location.latitude, content.location.longitude) } else if (content is MessageUserLocation) { @@ -108,7 +107,7 @@ object TelegramUiHelper { chat: TdApi.Chat, message: TdApi.Message ): LocationItem? { - val content = message.content + val content = OsmandLocationUtils.parseMessageContent(message, helper) return when (content) { is MessageOsmAndBotLocation -> botMessageToLocationItem(chat, content) is MessageUserLocation -> locationMessageToLocationItem(helper, chat, message) @@ -122,7 +121,7 @@ object TelegramUiHelper { chat: TdApi.Chat, message: TdApi.Message ): ChatItem? { - val content = message.content + val content = OsmandLocationUtils.parseMessageContent(message, helper) return when (content) { is MessageOsmAndBotLocation -> botMessageToChatItem(helper, chat, content) is TdApi.MessageLocation -> locationMessageToChatItem(helper, chat, message) @@ -139,7 +138,7 @@ object TelegramUiHelper { LocationItem().apply { chatId = chat.id chatTitle = chat.title - name = content.name + name = content.deviceName latLon = LatLon(content.lat, content.lon) placeholderId = R.drawable.img_user_picture lastUpdated = content.lastUpdated @@ -155,7 +154,7 @@ object TelegramUiHelper { message: TdApi.Message ): LocationItem? { val user = helper.getUser(message.senderUserId) ?: return null - val content = message.content + val content = OsmandLocationUtils.parseMessageContent(message, helper) return LocationItem().apply { chatId = chat.id chatTitle = chat.title @@ -182,7 +181,7 @@ object TelegramUiHelper { ChatItem().apply { chatId = chat.id chatTitle = chat.title - name = content.name + name = content.deviceName latLon = LatLon(content.lat, content.lon) photoPath = chat.photo?.small?.local?.path placeholderId = R.drawable.img_user_picture @@ -201,7 +200,7 @@ object TelegramUiHelper { message: TdApi.Message ): ChatItem? { val user = helper.getUser(message.senderUserId) ?: return null - val content = message.content + val content = OsmandLocationUtils.parseMessageContent(message, helper) return ChatItem().apply { chatId = chat.id chatTitle = chat.title @@ -250,7 +249,7 @@ object TelegramUiHelper { userLocations = userLocation grayscalePhotoPath = helper.getUserGreyPhotoPath(user) placeholderId = R.drawable.img_user_picture - chatWithBot = helper.isBot(userId) + chatWithBot = userLocation.deviceName.isNotEmpty() } } @@ -331,4 +330,4 @@ object TelegramUiHelper { override fun getVisibleName() = name } -} +} \ No newline at end of file diff --git a/OsmAnd-telegram/src/net/osmand/telegram/ui/MyLocationTabFragment.kt b/OsmAnd-telegram/src/net/osmand/telegram/ui/MyLocationTabFragment.kt index 312752229f..9b9bdc1996 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/ui/MyLocationTabFragment.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/ui/MyLocationTabFragment.kt @@ -17,9 +17,8 @@ import android.text.style.ForegroundColorSpan import android.view.* import android.view.animation.LinearInterpolator import android.widget.* -import net.osmand.telegram.ADDITIONAL_ACTIVE_TIME_VALUES_SEC -import net.osmand.telegram.R -import net.osmand.telegram.TelegramApplication +import net.osmand.telegram.* +import net.osmand.telegram.helpers.LocationMessages import net.osmand.telegram.helpers.TelegramHelper import net.osmand.telegram.helpers.TelegramHelper.TelegramListener import net.osmand.telegram.helpers.TelegramUiHelper @@ -727,7 +726,7 @@ class MyLocationTabFragment : Fragment(), TelegramListener { } private fun getStopSharingVisibility(expiresIn: Long) = - if (expiresIn > 0) View.VISIBLE else View.INVISIBLE + if (expiresIn > 0) View.VISIBLE else View.GONE private fun removeItem(chat: TdApi.Object) { items.remove(chat) diff --git a/OsmAnd-telegram/src/net/osmand/telegram/ui/SharingStatusBottomSheet.kt b/OsmAnd-telegram/src/net/osmand/telegram/ui/SharingStatusBottomSheet.kt index eaf2bc98b3..51ef8b14eb 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/ui/SharingStatusBottomSheet.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/ui/SharingStatusBottomSheet.kt @@ -48,7 +48,7 @@ class SharingStatusBottomSheet : DialogFragment() { val sharingStatus = items[i] as TelegramSettings.SharingStatus inflater.inflate(R.layout.item_with_three_text_lines, itemsCont, false).apply { val sharingStatusType = sharingStatus.statusType - val time = sharingStatus.locationTime + val time = sharingStatus.locationTime * 1000 findViewById(R.id.icon).setImageDrawable(uiUtils.getIcon(sharingStatusType.iconId, sharingStatusType.iconColorRes)) findViewById(R.id.title).text = sharingStatus.getTitle(app) @@ -74,6 +74,9 @@ class SharingStatusBottomSheet : DialogFragment() { if (sharingStatusType.canResendLocation) { if (i == 0) { setOnClickListener { + app.shareLocationHelper.checkNetworkType() + app.settings.prepareForSharingNewMessages() + app.shareLocationHelper.checkAndSendBufferMessages() app.forceUpdateMyLocation() dismiss() } diff --git a/OsmAnd-telegram/src/net/osmand/telegram/ui/TimelineTabFragment.kt b/OsmAnd-telegram/src/net/osmand/telegram/ui/TimelineTabFragment.kt index 721b885056..bc7f48dd80 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/ui/TimelineTabFragment.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/ui/TimelineTabFragment.kt @@ -225,6 +225,7 @@ class TimelineTabFragment : Fragment() { if (item is TelegramUiHelper.LocationMessagesChatItem) { val userLocations = item.userLocations if (userLocations != null) { + holder.title?.text = if (item.chatWithBot) userLocations.deviceName else item.name val trackData = getDistanceAndCountedPoints(userLocations) val distance = OsmandFormatter.getFormattedDistance(trackData.dist, app) val groupDescrRowVisible = (!item.privateChat || item.chatWithBot) && item.userId != currentUserId @@ -242,7 +243,7 @@ class TimelineTabFragment : Fragment() { holder.distanceAndPointsTitle?.text = "$distance (${getString(R.string.points_size, trackData.points)}) $point " holder.userRow?.setOnClickListener { childFragmentManager.also { - UserGpxInfoFragment.showInstance(it, item.userId, item.chatId, trackData.minTime, trackData.maxTime) + UserGpxInfoFragment.showInstance(it, item.userId, item.chatId, userLocations.deviceName ,trackData.minTime, trackData.maxTime) } } } diff --git a/OsmAnd-telegram/src/net/osmand/telegram/ui/UserGpxInfoFragment.kt b/OsmAnd-telegram/src/net/osmand/telegram/ui/UserGpxInfoFragment.kt index 27c82e681c..a2b689cf0d 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/ui/UserGpxInfoFragment.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/ui/UserGpxInfoFragment.kt @@ -59,6 +59,7 @@ class UserGpxInfoFragment : BaseDialogFragment() { private var userId = -1 private var chatId = -1L + private var deviceName = "" override fun onCreateView( inflater: LayoutInflater, @@ -71,7 +72,11 @@ class UserGpxInfoFragment : BaseDialogFragment() { readFromBundle(savedInstanceState ?: arguments) val user = app.telegramHelper.getUser(userId) - if (user != null) { + if (deviceName.isNotEmpty()) { + mainView.findViewById(R.id.title).text = deviceName + TelegramUiHelper.setupPhoto(app, mainView.findViewById(R.id.user_icon), + null, R.drawable.img_user_placeholder, false) + } else if (user != null) { mainView.findViewById(R.id.title).text = TelegramUiHelper.getUserName(user) TelegramUiHelper.setupPhoto(app, mainView.findViewById(R.id.user_icon), telegramHelper.getUserPhotoPath(user), R.drawable.img_user_placeholder, false) @@ -226,6 +231,7 @@ class UserGpxInfoFragment : BaseDialogFragment() { bundle?.also { userId = it.getInt(USER_ID_KEY) chatId = it.getLong(CHAT_ID_KEY) + deviceName = it.getString(DEVICE_NAME_KEY, "") startCalendar.timeInMillis = it.getLong(START_KEY) endCalendar.timeInMillis = it.getLong(END_KEY) } @@ -248,7 +254,7 @@ class UserGpxInfoFragment : BaseDialogFragment() { private fun updateGpxInfo() { checkTime() - locationMessages = app.locationMessages.getMessagesForUserInChat(userId, chatId, startCalendar.timeInMillis, endCalendar.timeInMillis) + locationMessages = app.locationMessages.getMessagesForUserInChat(userId, chatId,deviceName, startCalendar.timeInMillis, endCalendar.timeInMillis) gpxFile = OsmandLocationUtils.convertLocationMessagesToGpxFiles(locationMessages).firstOrNull()?:GPXUtilities.GPXFile() updateGPXStatisticRow() @@ -373,16 +379,18 @@ class UserGpxInfoFragment : BaseDialogFragment() { 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 DEVICE_NAME_KEY = "device_name_key" private const val GPX_TRACK_COLOR = -65536 private const val MIN_OSMAND_BITMAP_VERSION_CODE = 330 - fun showInstance(fm: FragmentManager,userId:Int,chatId:Long, start: Long, end: Long): Boolean { + fun showInstance(fm: FragmentManager,userId:Int,chatId:Long,deviceName:String, start: Long, end: Long): Boolean { return try { val fragment = UserGpxInfoFragment().apply { arguments = Bundle().apply { putInt(USER_ID_KEY, userId) putLong(CHAT_ID_KEY, chatId) + putString(DEVICE_NAME_KEY, deviceName) putLong(START_KEY, start) putLong(END_KEY, end) } diff --git a/OsmAnd-telegram/src/net/osmand/telegram/utils/OsmandLocationUtils.kt b/OsmAnd-telegram/src/net/osmand/telegram/utils/OsmandLocationUtils.kt index 64eed09fc0..8a086b31d0 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/utils/OsmandLocationUtils.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/utils/OsmandLocationUtils.kt @@ -61,7 +61,11 @@ object OsmandLocationUtils { if (message.replyMarkup is TdApi.ReplyMarkupInlineKeyboard) { val replyMarkup = message.replyMarkup as TdApi.ReplyMarkupInlineKeyboard try { - deviceName = replyMarkup.rows[0][1].text.split("\\s".toRegex())[1] + if (replyMarkup.rows[0].size > 1) { + deviceName = replyMarkup.rows[0][1].text.split("\\s".toRegex())[1] + } else if (message.content is TdApi.MessageText) { + deviceName = (message.content as TdApi.MessageText).text.text.lines().firstOrNull()?.removePrefix(DEVICE_PREFIX) ?: "" + } } catch (e: Exception) { } @@ -69,85 +73,61 @@ object OsmandLocationUtils { return deviceName } - fun parseOsmAndBotLocation(message: TdApi.Message): MessageOsmAndBotLocation { + fun parseMapLocation(message: TdApi.Message, botLocation: Boolean): MessageLocation { + val res = if (botLocation) MessageOsmAndBotLocation() else MessageUserLocation() val messageLocation = message.content as TdApi.MessageLocation - return MessageOsmAndBotLocation().apply { - name = getOsmAndBotDeviceName(message) + res.apply { lat = messageLocation.location.latitude lon = messageLocation.location.longitude lastUpdated = getLastUpdatedTime(message) + type = LocationMessages.TYPE_MAP + } + if (res is MessageOsmAndBotLocation) { + res.deviceName = getOsmAndBotDeviceName(message) } - } - 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) - type = LocationMessages.TYPE_USER_MAP - } + return res } fun parseMessage(message: TdApi.Message, helper: TelegramHelper, previousMessageLatLon: LatLon?): LocationMessage? { - var locationMessage: LocationMessage? = null - val oldContent = message.content - 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) - } - 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 (previousMessageLatLon != null) { - MapUtils.getDistance(previousMessageLatLon, 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, message.id, distanceFromPrev) - } - - return locationMessage + val parsedContent = parseMessageContent(message, helper) + return createLocationMessage(message, helper, parsedContent, previousMessageLatLon) } - fun getMessageType(message: TdApi.Message, helper: TelegramHelper): Int { - val fromBot = helper.isOsmAndBot(message.senderUserId) + fun parseMessageContent(message: TdApi.Message, helper: TelegramHelper): MessageLocation? { + val senderUserId = helper.getSenderMessageId(message) + val fromBot = helper.isOsmAndBot(senderUserId) val viaBot = helper.isOsmAndBot(message.viaBotUserId) + return when (message.content) { + is TdApi.MessageText -> parseTextLocation((message.content as TdApi.MessageText).text, (fromBot || viaBot)) + is TdApi.MessageLocation -> parseMapLocation(message, (fromBot || viaBot)) + is MessageLocation -> message.content as MessageLocation + else -> null + } + } + + fun createLocationMessage(message: TdApi.Message, helper: TelegramHelper, content:MessageLocation?, previousMessageLatLon: LatLon?):LocationMessage?{ + if (content == null) { + return null + } + val senderUserId = helper.getSenderMessageId(message) + val messageType = getMessageType(message) + val distanceFromPrev = if (previousMessageLatLon != null) MapUtils.getDistance(previousMessageLatLon, content.lat, content.lon) else 0.0 + val deviceName = if (content is MessageOsmAndBotLocation) content.deviceName else "" + + return LocationMessage(senderUserId, message.chatId, content.lat, content.lon, + content.altitude, content.speed, content.hdop, content.bearing, + content.lastUpdated * 1000L, messageType, message.id, distanceFromPrev, deviceName + ) + } + + fun getMessageType(message: TdApi.Message): Int { 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 + return when (oldContent) { + is TdApi.MessageText -> LocationMessages.TYPE_TEXT + is TdApi.MessageLocation -> LocationMessages.TYPE_MAP + is MessageLocation -> oldContent.type + else -> -1 } } @@ -171,23 +151,23 @@ object OsmandLocationUtils { fun parseOsmAndBotLocationContent(oldContent: MessageOsmAndBotLocation, content: TdApi.MessageContent): MessageOsmAndBotLocation { val messageLocation = content as TdApi.MessageLocation return MessageOsmAndBotLocation().apply { - name = oldContent.name + deviceName = oldContent.deviceName lat = messageLocation.location.latitude lon = messageLocation.location.longitude lastUpdated = (System.currentTimeMillis() / 1000).toInt() - type = LocationMessages.TYPE_BOT_MAP + type = LocationMessages.TYPE_MAP } } - fun parseTextLocation(text: TdApi.FormattedText, botLocation: Boolean = true): MessageLocation { + fun parseTextLocation(text: TdApi.FormattedText, botLocation: Boolean): MessageLocation { val res = if (botLocation) MessageOsmAndBotLocation() else MessageUserLocation() - res.type = if (botLocation) LocationMessages.TYPE_BOT_TEXT else LocationMessages.TYPE_USER_TEXT + res.type = LocationMessages.TYPE_TEXT var locationNA = false for (s in text.text.lines()) { when { s.startsWith(DEVICE_PREFIX) -> { if (res is MessageOsmAndBotLocation) { - res.name = s.removePrefix(DEVICE_PREFIX) + res.deviceName = s.removePrefix(DEVICE_PREFIX) } } s.startsWith(LOCATION_PREFIX) || s.startsWith(LAST_LOCATION_PREFIX) -> { @@ -229,7 +209,7 @@ object OsmandLocationUtils { if (timeIndex != -1) { val updatedS = locStr.substring(timeIndex, locStr.length) res.lastUpdated = - (parseTime(updatedS.removePrefix("(").removeSuffix(")")) / 1000).toInt() + (parseTime(updatedS.removePrefix("(").removeSuffix(")")) / 1000).toInt() } } } catch (e: Exception) { @@ -275,7 +255,7 @@ object OsmandLocationUtils { val parsedTime = (parseTime(updatedS.trim()) / 1000).toInt() val currentTime = (System.currentTimeMillis() / 1000) - 1 res.lastUpdated = - if (parsedTime < currentTime) parsedTime else currentTime.toInt() + if (parsedTime < currentTime) parsedTime else currentTime.toInt() } } } @@ -491,10 +471,10 @@ object OsmandLocationUtils { class MessageOsmAndBotLocation : MessageLocation() { - var name: String = "" + var deviceName: String = "" internal set - override fun isValid() = name != "" && lat != Double.NaN && lon != Double.NaN + override fun isValid() = deviceName != "" && lat != Double.NaN && lon != Double.NaN } class MessageUserLocation : MessageLocation() {