diff --git a/OsmAnd-telegram/res/layout/fragment_user_gpx_info.xml b/OsmAnd-telegram/res/layout/fragment_user_gpx_info.xml
index 4d7636dc1b..205496fddf 100644
--- a/OsmAnd-telegram/res/layout/fragment_user_gpx_info.xml
+++ b/OsmAnd-telegram/res/layout/fragment_user_gpx_info.xml
@@ -188,6 +188,24 @@
+
+
#5959FF
+ #F54522
+
diff --git a/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt b/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt
index fe0c5f2bf1..c90caecd77 100644
--- a/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt
+++ b/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt
@@ -27,6 +27,8 @@ val ADDITIONAL_ACTIVE_TIME_VALUES_SEC = listOf(15 * 60L, 30 * 60L, 60 * 60L, 180
const val SHARE_DEVICES_KEY = "devices"
+const val LIVE_TRACKS_KEY = "live_tracks"
+
private val SEND_MY_LOC_VALUES_SEC =
listOf(1L, 2L, 3L, 5L, 10L, 15L, 30L, 60L, 90L, 2 * 60L, 3 * 60L, 5 * 60L)
private val STALE_LOC_VALUES_SEC =
@@ -110,6 +112,7 @@ class TelegramSettings(private val app: TelegramApplication) {
private var shareChatsInfo = ConcurrentHashMap()
private var hiddenOnMapChats: Set = emptySet()
private var shareDevices: Set = emptySet()
+ private var liveTracksInfo: Set = emptySet()
var sharingStatusChanges = ConcurrentLinkedQueue()
@@ -163,6 +166,19 @@ class TelegramSettings(private val app: TelegramApplication) {
fun isShowingChatOnMap(chatId: Long) = !hiddenOnMapChats.contains(chatId)
+ fun isLiveTrackEnabled(userId: Int, chatId: Long, deviceName: String) =
+ liveTracksInfo.any { (it.chatId == chatId && it.userId == userId && it.deviceName == deviceName) }
+
+ fun updateLiveTrack(userId: Int, chatId: Long, deviceName: String, enable: Boolean) {
+ val tracksInfo = liveTracksInfo.toMutableList()
+ if (enable) {
+ tracksInfo.add(LiveTrackInfo(userId, chatId, deviceName))
+ } else {
+ tracksInfo.remove(LiveTrackInfo(userId, chatId, deviceName))
+ }
+ liveTracksInfo = tracksInfo.toHashSet()
+ }
+
fun removeNonexistingChats(presentChatIds: List) {
val hiddenChats = hiddenOnMapChats.toMutableList()
hiddenChats.intersect(presentChatIds)
@@ -610,6 +626,11 @@ class TelegramSettings(private val app: TelegramApplication) {
edit.putString(PROXY_PREFERENCES_KEY, jsonObjectProxy.toString())
}
+ val jsonArrayLiveTracks = convertLiveTracksInfoToJson()
+ if (jsonArrayLiveTracks != null) {
+ edit.putString(LIVE_TRACKS_KEY, jsonArrayLiveTracks.toString())
+ }
+
edit.apply()
}
@@ -674,7 +695,13 @@ class TelegramSettings(private val app: TelegramApplication) {
try {
parseProxyPreferences(JSONObject(prefs.getString(PROXY_PREFERENCES_KEY, "")))
} catch (e: JSONException) {
- e.printStackTrace()
+ log.error(e)
+ }
+
+ try {
+ parseLiveTracks(JSONArray(prefs.getString(LIVE_TRACKS_KEY, "")))
+ } catch (e: JSONException) {
+ log.error(e)
}
}
@@ -699,6 +726,23 @@ class TelegramSettings(private val app: TelegramApplication) {
}
}
+ private fun convertLiveTracksInfoToJson(): JSONArray? {
+ return try {
+ JSONArray().apply {
+ liveTracksInfo.forEach { liveTrackInfo ->
+ val obj = JSONObject()
+ obj.put(LiveTrackInfo.USER_ID, liveTrackInfo.userId)
+ obj.put(LiveTrackInfo.CHAT_ID, liveTrackInfo.chatId)
+ obj.put(LiveTrackInfo.DEVICE_NAME, liveTrackInfo.deviceName)
+ put(obj)
+ }
+ }
+ } catch (e: JSONException) {
+ log.error(e)
+ null
+ }
+ }
+
private fun convertProxyPrefToJson(): JSONObject? {
return try {
val proxyPref = currentProxyPref
@@ -746,7 +790,7 @@ class TelegramSettings(private val app: TelegramApplication) {
}
jArray
} catch (e: JSONException) {
- e.printStackTrace()
+ log.error(e)
null
}
}
@@ -799,6 +843,19 @@ class TelegramSettings(private val app: TelegramApplication) {
}
}
+ private fun parseLiveTracks(json: JSONArray) {
+ val list = mutableListOf()
+ for (i in 0 until json.length()) {
+ val obj = json.getJSONObject(i)
+ val userId = obj.optInt(LiveTrackInfo.USER_ID)
+ val chatId = obj.optLong(LiveTrackInfo.CHAT_ID)
+ val deviceName = obj.optString(LiveTrackInfo.DEVICE_NAME)
+
+ list.add(LiveTrackInfo(userId, chatId, deviceName))
+ }
+ liveTracksInfo = list.toHashSet()
+ }
+
private fun parseShareDevices(json: String) {
shareDevices = OsmandApiUtils.parseJsonContents(json).toHashSet()
}
@@ -1122,6 +1179,15 @@ class TelegramSettings(private val app: TelegramApplication) {
}
}
+ data class LiveTrackInfo(val userId: Int, val chatId: Long, val deviceName: String) {
+ companion object {
+
+ internal const val USER_ID = "userId"
+ internal const val CHAT_ID = "chatId"
+ internal const val DEVICE_NAME = "deviceName"
+ }
+ }
+
enum class ProxyType {
MTPROTO, SOCKS5
}
diff --git a/OsmAnd-telegram/src/net/osmand/telegram/ui/UserGpxInfoFragment.kt b/OsmAnd-telegram/src/net/osmand/telegram/ui/UserGpxInfoFragment.kt
index a2b689cf0d..722c90b35e 100644
--- a/OsmAnd-telegram/src/net/osmand/telegram/ui/UserGpxInfoFragment.kt
+++ b/OsmAnd-telegram/src/net/osmand/telegram/ui/UserGpxInfoFragment.kt
@@ -7,6 +7,7 @@ import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
+import android.graphics.drawable.LayerDrawable
import android.os.Build
import android.os.Bundle
import android.support.design.widget.Snackbar
@@ -46,6 +47,7 @@ class UserGpxInfoFragment : BaseDialogFragment() {
private lateinit var timeStartBtn: TextView
private lateinit var dateEndBtn: TextView
private lateinit var timeEndBtn: TextView
+ private lateinit var liveBtn: TextView
private lateinit var avgElevationTv: TextView
private lateinit var avgSpeedTv: TextView
@@ -122,6 +124,15 @@ class UserGpxInfoFragment : BaseDialogFragment() {
dateEndBtn = mainView.findViewById(R.id.date_end_btn)
timeEndBtn = mainView.findViewById(R.id.time_end_btn)
+ liveBtn = mainView.findViewById(R.id.live_btn).apply {
+ setOnClickListener {
+ val enabled = settings.isLiveTrackEnabled(userId, chatId, deviceName)
+ settings.updateLiveTrack(userId, chatId, deviceName, !enabled)
+ updateLiveTrackBtn()
+ }
+ }
+ updateLiveTrackBtn()
+
dateStartBtn.setOnClickListener { selectStartDate() }
timeStartBtn.setOnClickListener { selectStartTime() }
dateEndBtn.setOnClickListener { selectEndDate() }
@@ -241,6 +252,15 @@ class UserGpxInfoFragment : BaseDialogFragment() {
textView.setTextColor(AndroidUtils.createPressedColorStateList(app, true, R.color.ctrl_active_light, R.color.ctrl_light))
}
+ private fun updateLiveTrackBtn() {
+ val enabled = settings.isLiveTrackEnabled(userId, chatId, deviceName)
+ val icon = getLiveTrackBtnIcon(enabled)
+ val normalTextColor = if (enabled) R.color.ctrl_active_light else R.color.secondary_text_light
+
+ liveBtn.setTextColor(AndroidUtils.createPressedColorStateList(app, true, normalTextColor, R.color.ctrl_light))
+ liveBtn.setCompoundDrawablesWithIntrinsicBounds(null, null, icon, null)
+ }
+
private fun getShareIcon(): Drawable? {
val normal = app.uiUtils.getActiveIcon(R.drawable.ic_action_share)
if (Build.VERSION.SDK_INT >= 21) {
@@ -252,9 +272,27 @@ class UserGpxInfoFragment : BaseDialogFragment() {
return normal
}
+ private fun getLiveTrackBtnIcon(enabled: Boolean): Drawable? {
+ val iconColor = if (enabled) R.color.live_track_active_icon else R.color.icon_light
+
+ val layers = arrayOfNulls(2)
+ layers[0] = app.uiUtils.getIcon(R.drawable.ic_action_round_shape)
+ layers[1] = app.uiUtils.getIcon(R.drawable.ic_action_record, iconColor)
+
+ if (Build.VERSION.SDK_INT >= 21 && !enabled) {
+ val normal = layers[1]
+ val active = app.uiUtils.getIcon(R.drawable.ic_action_record, R.color.live_track_active_icon)
+ if (normal != null && active != null) {
+ layers[1] = AndroidUtils.createPressedStateListDrawable(normal, active)
+ }
+ }
+
+ return LayerDrawable(layers)
+ }
+
private fun updateGpxInfo() {
checkTime()
- locationMessages = app.locationMessages.getMessagesForUserInChat(userId, chatId,deviceName, startCalendar.timeInMillis, endCalendar.timeInMillis)
+ locationMessages = app.locationMessages.getMessagesForUserInChat(userId, chatId, deviceName, startCalendar.timeInMillis, endCalendar.timeInMillis)
gpxFile = OsmandLocationUtils.convertLocationMessagesToGpxFiles(locationMessages).firstOrNull()?:GPXUtilities.GPXFile()
updateGPXStatisticRow()