Add devices buffer initial commit

This commit is contained in:
Chumva 2019-02-08 19:12:17 +02:00
parent a354ce2fa0
commit 4fed0ed4c5
14 changed files with 406 additions and 417 deletions

View file

@ -107,7 +107,8 @@
<LinearLayout
android:id="@+id/show_on_map_row"
android:layout_width="match_parent"
android:layout_height="@dimen/list_item_height_big"
android:layout_height="wrap_content"
android:minHeight="@dimen/list_item_height_big"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingLeft="@dimen/content_padding_standard"

View file

@ -187,7 +187,11 @@ class TelegramLocationProvider(private val app: TelegramApplication) : SensorEve
@SuppressLint("MissingPermission")
override fun onGpsStatusChanged(event: Int) {
gpsStatus = service.getGpsStatus(gpsStatus)
try {
gpsStatus = service.getGpsStatus(gpsStatus)
} catch (e: Exception) {
e.printStackTrace()
}
updateGPSInfo(gpsStatus)
updateLocation(lastKnownLocation)
}

View file

@ -17,7 +17,6 @@ import net.osmand.telegram.helpers.TelegramHelper.TelegramIncomingMessagesListen
import net.osmand.telegram.helpers.TelegramHelper.TelegramOutgoingMessagesListener
import net.osmand.telegram.notifications.TelegramNotification.NotificationType
import net.osmand.telegram.utils.AndroidUtils
import net.osmand.telegram.utils.OsmandLocationUtils
import org.drinkless.td.libcore.telegram.TdApi
import java.util.*
@ -296,10 +295,8 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
messages.forEach {
app().settings.updateShareInfo(it)
app().shareLocationHelper.checkAndSendBufferMessagesToChat(it.chatId)
if (it.sendingState == null && (it.content is TdApi.MessageLocation || it.content is TdApi.MessageText)) {
if (!it.isOutgoing) {
app().locationMessages.addNewLocationMessage(it)
}
if (it.sendingState == null && !it.isOutgoing && (it.content is TdApi.MessageLocation || it.content is TdApi.MessageText)) {
app().locationMessages.addNewLocationMessage(it)
}
}
}

View file

@ -83,6 +83,7 @@ private const val BATTERY_OPTIMISATION_ASKED = "battery_optimisation_asked"
private const val MONITORING_ENABLED = "monitoring_enabled"
private const val SHARING_INITIALIZATION_TIME = 60 * 2L // 2 minutes
private const val WAITING_TDLIB_TIME = 30 // 2 seconds
private const val GPS_UPDATE_EXPIRED_TIME = 60 * 3L // 3 minutes
@ -188,12 +189,23 @@ class TelegramSettings(private val app: TelegramApplication) {
fun updateCurrentSharingMode(sharingMode: String) {
if (currentSharingMode != sharingMode) {
shareChatsInfo.forEach { (_, shareInfo) ->
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) {

View file

@ -25,14 +25,27 @@ class LocationMessages(val app: TelegramApplication) {
init {
dbHelper = SQLiteHelper(app)
readBufferedMessages()
readLastMessages()
}
fun getBufferedMessages(): List<BufferMessage> {
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<BufferMessage> {
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<LocationMessage> {
@ -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<LocationMessage> {
return dbHelper.getMessagesForUserInChat(userId, chatId, start, end)
fun getMessagesForUserInChat(userId: Int, chatId: Long, deviceName: String, start: Long, end: Long): List<LocationMessage> {
return dbHelper.getMessagesForUserInChat(userId, chatId,deviceName, start, end)
}
fun getMessagesForUser(userId: Int, start: Long, end: Long): List<LocationMessage> {
@ -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<LocationMessage> {
@ -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<LocationMessage> {
val res = arrayListOf<LocationMessage>()
readableDatabase?.rawQuery(
@ -187,42 +180,35 @@ class LocationMessages(val app: TelegramApplication) {
internal fun getIngoingUserLocations(start: Long, end: Long): List<UserLocations> {
val res = arrayListOf<UserLocations>()
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<Int, MutableList<UserTrkSegment>>? = null
var userLocationsListByType: MutableList<LocationMessage>? = 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<LocationMessage> {
internal fun getMessagesForUserInChat(userId: Int, chatId: Long, deviceName: String, start: Long, end: Long): List<LocationMessage> {
val res = arrayListOf<LocationMessage>()
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<LocationHistoryPoint, LatLon> {
val res = mutableMapOf<LocationHistoryPoint, LatLon>()
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<LocationHistoryPoint, LatLon> {
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<Int, List<UserTrkSegment>>
){
val userId: Int,
val chatId: Long,
val deviceName: String,
val locationsByType: Map<Int, List<UserTrkSegment>>
) {
fun getUniqueSegments(): List<UserTrkSegment> {
// TODO TYPE_BOT_MAP. TYPE_BOT_TEXT, TYPE_USER_BOTH, TYPE_BOT_BOTH - delete
val list = mutableListOf<UserTrkSegment>()
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
}
}
}

View file

@ -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
}

View file

@ -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}")
}
}
}

View file

@ -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<Long, List<TdApi.Message>> {
val res = mutableMapOf<Long, MutableList<TdApi.Message>>()
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)

View file

@ -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
}
}
}

View file

@ -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)

View file

@ -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<ImageView>(R.id.icon).setImageDrawable(uiUtils.getIcon(sharingStatusType.iconId, sharingStatusType.iconColorRes))
findViewById<TextView>(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()
}

View file

@ -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)
}
}
}

View file

@ -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<TextView>(R.id.title).text = deviceName
TelegramUiHelper.setupPhoto(app, mainView.findViewById<ImageView>(R.id.user_icon),
null, R.drawable.img_user_placeholder, false)
} else if (user != null) {
mainView.findViewById<TextView>(R.id.title).text = TelegramUiHelper.getUserName(user)
TelegramUiHelper.setupPhoto(app, mainView.findViewById<ImageView>(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)
}

View file

@ -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() {