diff --git a/OsmAnd-telegram/res/layout/my_location_sharing_chat.xml b/OsmAnd-telegram/res/layout/my_location_sharing_chat.xml index 0f70f54286..baf007cc7c 100644 --- a/OsmAnd-telegram/res/layout/my_location_sharing_chat.xml +++ b/OsmAnd-telegram/res/layout/my_location_sharing_chat.xml @@ -199,31 +199,12 @@ - - - - diff --git a/OsmAnd-telegram/res/values/strings.xml b/OsmAnd-telegram/res/values/strings.xml index eaa5488040..be66101058 100644 --- a/OsmAnd-telegram/res/values/strings.xml +++ b/OsmAnd-telegram/res/values/strings.xml @@ -1,4 +1,5 @@ + sent (%1$d in buffer) %1$d points Date Collected diff --git a/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt b/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt index 40d009ea0c..bed68ca2c3 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt @@ -580,7 +580,6 @@ class TelegramSettings(private val app: TelegramApplication) { obj.put(ShareChatInfo.LAST_SEND_TEXT_TIME_KEY, chatInfo.lastSendTextMessageTime) obj.put(ShareChatInfo.PENDING_TEXT_MESSAGE_KEY, chatInfo.pendingTextMessage) obj.put(ShareChatInfo.PENDING_MAP_MESSAGE_KEY, chatInfo.pendingMapMessage) - obj.put(ShareChatInfo.COLLECTED_MESSAGES_KEY, chatInfo.collectedMessages) obj.put(ShareChatInfo.SENT_MESSAGES_KEY, chatInfo.sentMessages) obj.put(ShareChatInfo.PENDING_TDLIB_KEY, chatInfo.pendingTdLib) jArray.put(obj) @@ -611,7 +610,6 @@ class TelegramSettings(private val app: TelegramApplication) { lastSendTextMessageTime = obj.optInt(ShareChatInfo.LAST_SEND_TEXT_TIME_KEY) pendingTextMessage = obj.optBoolean(ShareChatInfo.PENDING_TEXT_MESSAGE_KEY) pendingMapMessage = obj.optBoolean(ShareChatInfo.PENDING_MAP_MESSAGE_KEY) - collectedMessages = obj.optInt(ShareChatInfo.COLLECTED_MESSAGES_KEY) sentMessages = obj.optInt(ShareChatInfo.SENT_MESSAGES_KEY) pendingTdLib = obj.optInt(ShareChatInfo.PENDING_TDLIB_KEY) } @@ -901,7 +899,6 @@ class TelegramSettings(private val app: TelegramApplication) { var lastSuccessfulSendTimeMs = -1L var lastSendTextMessageTime = -1 var lastSendMapMessageTime = -1 - var collectedMessages = 0 var sentMessages = 0 var pendingTdLib = 0 var pendingTextMessage = false @@ -942,7 +939,6 @@ class TelegramSettings(private val app: TelegramApplication) { internal const val LAST_SEND_TEXT_TIME_KEY = "lastSendTextMessageTime" internal const val PENDING_TEXT_MESSAGE_KEY = "pendingTextMessage" internal const val PENDING_MAP_MESSAGE_KEY = "pendingMapMessage" - internal const val COLLECTED_MESSAGES_KEY = "collectedMessages" internal const val SENT_MESSAGES_KEY = "sentMessages" internal const val PENDING_TDLIB_KEY = "sentMessages" } diff --git a/OsmAnd-telegram/src/net/osmand/telegram/helpers/LocationMessages.kt b/OsmAnd-telegram/src/net/osmand/telegram/helpers/LocationMessages.kt index 733a79c88f..e381ef8213 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/helpers/LocationMessages.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/helpers/LocationMessages.kt @@ -39,8 +39,8 @@ class LocationMessages(val app: TelegramApplication) { return dbHelper.getIngoingMessages(currentUserId, start, end) } - fun getIngoingUserLocations(currentUserId: Int, start: Long, end: Long): List { - return dbHelper.getIngoingUserLocations(currentUserId, start, end) + fun getIngoingUserLocations(start: Long, end: Long): List { + return dbHelper.getIngoingUserLocations(start, end) } fun getMessagesForUserInChat(userId: Int, chatId: Long, start: Long, end: Long): List { @@ -51,10 +51,6 @@ class LocationMessages(val app: TelegramApplication) { return dbHelper.getMessagesForUser(userId, start, end) } - fun getUserLocations(userId: Int, start: Long, end: Long): UserLocations? { - return dbHelper.getUserLocations(userId, start, end) - } - fun addBufferedMessage(message: BufferMessage) { log.debug("addBufferedMessage $message") val messages = mutableListOf(*this.bufferedMessages.toTypedArray()) @@ -103,6 +99,10 @@ class LocationMessages(val app: TelegramApplication) { dbHelper.removeBufferedMessage(message) } + fun getBufferedMessagesCount(): Int { + return bufferedMessages.size + } + private fun readBufferedMessages() { this.bufferedMessages = dbHelper.getBufferedMessages() } @@ -153,33 +153,6 @@ class LocationMessages(val app: TelegramApplication) { return res } - internal fun getUserLocations(userId: Int, start: Long, end: Long): UserLocations? { - var userLocations: UserLocations? = null - readableDatabase?.rawQuery( - "$TIMELINE_TABLE_SELECT WHERE $COL_USER_ID = ? AND $COL_TIME BETWEEN $start AND $end ORDER BY $COL_CHAT_ID ASC, $COL_TYPE DESC, $COL_TIME ASC ", - arrayOf(userId.toString()))?.apply { - if (moveToFirst()) { - var type = -1 - val userLocationsMap: MutableMap> = mutableMapOf() - userLocations = UserLocations(userId, 0, userLocationsMap) - var userLocationsListByType: MutableList? = null - do { - val locationMessage = readLocationMessage(this@apply) - if (type != locationMessage.type) { - type = locationMessage.type - userLocationsListByType = mutableListOf() - userLocationsListByType.add(locationMessage) - userLocationsMap.set(type, userLocationsListByType) - } else { - userLocationsListByType?.add(locationMessage) - } - } while (moveToNext()) - } - close() - } - return userLocations - } - internal fun getPreviousMessage(userId: Int, chatId: Long): LocationMessage? { var res:LocationMessage? = null readableDatabase?.rawQuery( @@ -208,39 +181,47 @@ class LocationMessages(val app: TelegramApplication) { return res } - internal fun getIngoingUserLocations(currentUserId: Int, start: Long, end: Long): List { + internal fun getIngoingUserLocations(start: Long, end: Long): List { val res = arrayListOf() readableDatabase?.rawQuery( - "$TIMELINE_TABLE_SELECT WHERE $COL_USER_ID != ? AND $COL_TIME BETWEEN $start AND $end ORDER BY $COL_USER_ID, $COL_CHAT_ID, $COL_TYPE DESC, $COL_TIME ", - arrayOf(currentUserId.toString()))?.apply { + "$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 { if (moveToFirst()) { - var type = -1 var userId = -1 var chatId = -1L - var userLocations: UserLocations? - var userLocationsMap: MutableMap>? = null + // TODO query bot name + var botName = "" + var userLocations: UserLocations? = null + var userLocationsMap: MutableMap>? = null var userLocationsListByType: MutableList? = null + var segment: UserTrkSegment? = null do { val locationMessage = readLocationMessage(this@apply) - if (userId != locationMessage.userId || chatId != locationMessage.chatId) { - userId = locationMessage.userId - chatId = locationMessage.chatId - type = locationMessage.type + userId = locationMessage.userId + chatId = locationMessage.chatId + // TODO compare bot name as well + if(userLocations == null || userLocations.userId != userId || + userLocations.chatId != chatId) { userLocationsMap = mutableMapOf() - userLocationsListByType = mutableListOf() - userLocationsListByType.add(locationMessage) - userLocationsMap[type] = userLocationsListByType - userLocations = UserLocations(userId, chatId, userLocationsMap) + userLocations = UserLocations(userId, chatId, botName, userLocationsMap) res.add(userLocations) + segment = null } - if (type != locationMessage.type) { - type = locationMessage.type - userLocationsListByType = mutableListOf() - userLocationsListByType.add(locationMessage) - userLocationsMap?.set(type, userLocationsListByType) - } else { - userLocationsListByType?.add(locationMessage) + 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) + } + segment.maxTime = locationMessage.time + segment.points.add(locationMessage) } while (moveToNext()) } close() @@ -438,8 +419,58 @@ class LocationMessages(val app: TelegramApplication) { data class UserLocations( var userId: Int, var chatId: Long, - var locationsByType: Map> - ) + var botName: String, + var 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 + } + list.addAll(locationsByType.get(TYPE_USER_TEXT)?: emptyList()) + val mapList = locationsByType.get(TYPE_USER_MAP)?: emptyList(); + mapList.forEach { + var ti = 0; + while(ti < list.size && list[ti].maxTime < it.minTime) { + ti++; + } + if(ti < list.size && list[ti].minTime > it.maxTime ) { + list.add(ti, it) + } else if(ti == list.size) { + list.add(it) + } + } + + + return list + } + } + + data class UserTrkSegment( + val points: MutableList, + var distance: Double, + var type: Int, + var minTime: Long, + var maxTime: Long + ) { + fun newer(other: UserTrkSegment): Boolean { + return other.maxTime < maxTime; + } + + + fun overlap(other: UserTrkSegment): Boolean { + + if(other.maxTime < maxTime) { + return other.maxTime > minTime; + } else { + return other.minTime < maxTime; + } + } + + } data class LocationHistoryPoint( val userId: Int, diff --git a/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShareLocationHelper.kt b/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShareLocationHelper.kt index c76f8c8d2c..39f765aef6 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShareLocationHelper.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShareLocationHelper.kt @@ -238,7 +238,6 @@ class ShareLocationHelper(private val app: TelegramApplication) { log.debug("prepareTextMessage $message") if (shareInfo.currentTextMessageId == -1L) { if (shareInfo.pendingTextMessage) { - shareInfo.collectedMessages++ app.locationMessages.addBufferedMessage(message) } else { if (isBot) { @@ -254,7 +253,6 @@ class ShareLocationHelper(private val app: TelegramApplication) { if (shareInfo.pendingTdLib < 10) { app.telegramHelper.editTextLocation(shareInfo, message) } else { - shareInfo.collectedMessages++ app.locationMessages.addBufferedMessage(message) } } @@ -265,7 +263,6 @@ class ShareLocationHelper(private val app: TelegramApplication) { log.debug("prepareMapMessage $message") if (shareInfo.currentMapMessageId == -1L) { if (shareInfo.pendingMapMessage) { - shareInfo.collectedMessages++ app.locationMessages.addBufferedMessage(message) } else { if (isBot) { @@ -281,7 +278,6 @@ class ShareLocationHelper(private val app: TelegramApplication) { if (shareInfo.pendingTdLib < 10) { app.telegramHelper.editMapLocation(shareInfo, message) } else { - shareInfo.collectedMessages++ app.locationMessages.addBufferedMessage(message) } } @@ -291,7 +287,6 @@ class ShareLocationHelper(private val app: TelegramApplication) { private fun prepareMapAndTextMessage(shareInfo: TelegramSettings.ShareChatInfo, message: BufferMessage, isBot:Boolean, sharingMode: String) { log.debug("prepareMapAndTextMessage $message") if (shareInfo.pendingMapMessage || shareInfo.pendingTextMessage || shareInfo.pendingTdLib >= 10) { - shareInfo.collectedMessages++ app.locationMessages.addBufferedMessage(message) } else { if (isBot) { diff --git a/OsmAnd-telegram/src/net/osmand/telegram/ui/MyLocationTabFragment.kt b/OsmAnd-telegram/src/net/osmand/telegram/ui/MyLocationTabFragment.kt index 38243f6704..ce2617f793 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/ui/MyLocationTabFragment.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/ui/MyLocationTabFragment.kt @@ -718,12 +718,12 @@ class MyLocationTabFragment : Fragment(), TelegramListener { } holder.gpsPointsCollected?.apply { if (shareInfo != null) { - text = "${shareInfo.pendingTdLib + shareInfo.collectedMessages}" + text = " ${shareInfo.sentMessages}" } } holder.gpsPointsSent?.apply { if (shareInfo != null) { - text = "${shareInfo.sentMessages}" + text = getString(R.string.gps_points_in_buffer,shareInfo.pendingTdLib + app.locationMessages.getBufferedMessagesCount()) } } } @@ -764,7 +764,7 @@ class MyLocationTabFragment : Fragment(), TelegramListener { val stopSharingFirstPart: TextView? = view.findViewById(R.id.ending_in_first_part) val stopSharingSecondPart: TextView? = view.findViewById(R.id.ending_in_second_part) val gpsPointsCollected: TextView? = view.findViewById(R.id.gps_points_collected) - val gpsPointsSent: TextView? = view.findViewById(R.id.gps_points_sent) + val gpsPointsSent: TextView? = view.findViewById(R.id.gps_points_in_buffer_txt) } } diff --git a/OsmAnd-telegram/src/net/osmand/telegram/ui/TimelineTabFragment.kt b/OsmAnd-telegram/src/net/osmand/telegram/ui/TimelineTabFragment.kt index de5ea5f48e..06c1dbc0f9 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/ui/TimelineTabFragment.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/ui/TimelineTabFragment.kt @@ -158,20 +158,13 @@ class TimelineTabFragment : Fragment() { private fun updateList() { val res = mutableListOf() val currentUserId = telegramHelper.getCurrentUser()?.id - if (currentUserId != null) { - val currentUserLocations = app.locationMessages.getUserLocations(currentUserId, start, end) - if (currentUserLocations != null) { - TelegramUiHelper.userLocationsToChatItem(telegramHelper, currentUserLocations)?.also { chatItem -> - res.add(chatItem) - } - } - val ingoingUserLocations = app.locationMessages.getIngoingUserLocations(currentUserId, start, end) + + val ingoingUserLocations = app.locationMessages.getIngoingUserLocations(start, end) ingoingUserLocations.forEach { TelegramUiHelper.userLocationsToChatItem(telegramHelper, it)?.also { chatItem -> res.add(chatItem) } } - } adapter.items = sortAdapterItems(res) } @@ -214,18 +207,19 @@ class TimelineTabFragment : Fragment() { val userLocations = item.userLocations if(userLocations!=null){ - val pair = getDistanceAndCountedPoints(userLocations) - val distance = OsmandFormatter.getFormattedDistance(pair.first,app) + val trackData = getDistanceAndCountedPoints(userLocations) + val distance = OsmandFormatter.getFormattedDistance(trackData.dist,app) val name = if ((!item.privateChat || item.chatWithBot) && item.userId != currentUserId) item.getVisibleName() else "" holder.groupDescrContainer?.visibility = View.VISIBLE - holder.groupTitle?.text = "$distance (${getString(R.string.points_size, pair.second)}) $name" - } - TelegramUiHelper.setupPhoto(app, holder.groupImage, item.groupPhotoPath, item.placeholderId, false) - holder.userRow?.setOnClickListener { - childFragmentManager.also { - UserGpxInfoFragment.showInstance(it, item.userId, item.chatId, start, end) + holder.groupTitle?.text = "$distance (${getString(R.string.points_size, trackData.points)}) $name" + TelegramUiHelper.setupPhoto(app, holder.groupImage, item.groupPhotoPath, item.placeholderId, false) + holder.userRow?.setOnClickListener { + childFragmentManager.also { + UserGpxInfoFragment.showInstance(it, item.userId, item.chatId, trackData.minTime, trackData.maxTime) + } } } + holder.imageButton?.visibility = View.GONE holder.showOnMapRow?.visibility = View.GONE holder.bottomDivider?.visibility = if (lastItem) View.GONE else View.VISIBLE @@ -233,27 +227,20 @@ class TimelineTabFragment : Fragment() { } } - private fun getDistanceAndCountedPoints(userLocations: LocationMessages.UserLocations): Pair { - val textUserLoc = userLocations.locationsByType[LocationMessages.TYPE_USER_TEXT] - val textBotLoc = userLocations.locationsByType[LocationMessages.TYPE_BOT_TEXT] - var dist = 0.0 - var countedPoints = 0 - when { - textUserLoc != null -> textUserLoc.forEach { - dist += it.distanceFromPrev - countedPoints++ - } - textBotLoc != null -> textBotLoc.forEach { - dist += it.distanceFromPrev - countedPoints++ - } - else -> userLocations.locationsByType.values.firstOrNull()?.forEach { - dist += it.distanceFromPrev - countedPoints++ - } - } - return Pair(dist.toFloat(), countedPoints) + private fun getDistanceAndCountedPoints(userLocations: LocationMessages.UserLocations): UITrackData { + var uiTrackData= UITrackData(0.0f, 0, 0, 0) + + + userLocations.getUniqueSegments().forEach { + if(uiTrackData.minTime == 0L) { + uiTrackData.minTime = it.minTime + } + uiTrackData.dist += it.distance.toFloat(); + uiTrackData.points += it.points.size + uiTrackData.maxTime = it.maxTime + } + return uiTrackData } override fun getItemCount() = items.size @@ -276,6 +263,12 @@ class TimelineTabFragment : Fragment() { } } + data class UITrackData ( + var dist: Float, + var points: Int, + var minTime: Long, + var maxTime: Long + ) companion object { private const val ADAPTER_UPDATE_INTERVAL_MIL = 15 * 1000L // 15 sec }