Add additional setting initial commit and fix forward messages ids

This commit is contained in:
Chumva 2019-02-11 19:05:49 +02:00
parent ba5ded42df
commit 8186455239
19 changed files with 392 additions and 156 deletions

View file

@ -74,6 +74,35 @@
<include layout="@layout/list_item_divider"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/card_bg_color"
android:orientation="vertical">
<net.osmand.telegram.ui.views.TextViewEx
android:layout_width="match_parent"
android:layout_height="@dimen/list_header_height"
android:ellipsize="end"
android:gravity="center_vertical"
android:maxLines="1"
android:paddingLeft="@dimen/content_padding_standard"
android:paddingRight="@dimen/content_padding_standard"
android:text="@string/shared_string_appearance"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/list_item_title_text_size"
app:typeface="@string/font_roboto_medium"/>
<LinearLayout
android:id="@+id/gps_points_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"/>
</LinearLayout>
<include layout="@layout/list_item_divider"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -91,7 +120,7 @@
android:text="@string/share_location_as"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/list_item_title_text_size"
app:firstBaselineToTopHeight="25sp"
app:firstBaselineToTopHeight="28sp"
app:typeface="@string/font_roboto_medium" />
<net.osmand.telegram.ui.views.TextViewEx
@ -175,7 +204,7 @@
android:text="@string/osmand_connect"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/list_item_title_text_size"
app:firstBaselineToTopHeight="25sp"
app:firstBaselineToTopHeight="28sp"
app:typeface="@string/font_roboto_medium"/>
<net.osmand.telegram.ui.views.TextViewEx

View file

@ -44,7 +44,7 @@
android:layout_height="wrap_content"
android:textColor="?android:attr/textColorSecondary"
android:textSize="@dimen/list_item_description_text_size"
app:firstBaselineToTopHeight="20sp"
app:firstBaselineToTopHeight="14sp"
app:lastBaselineToBottomHeight="16sp"
app:typeface="@string/font_roboto_regular"
tools:text="Some long description"/>

View file

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:paddingLeft="@dimen/content_padding_standard"
android:paddingRight="@dimen/content_padding_standard"
tools:background="@color/card_bg_light">
<ImageView
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/image_button_padding"
android:layout_marginEnd="@dimen/content_padding_big"
android:layout_marginRight="@dimen/content_padding_big"
tools:src="@drawable/ic_action_live_now"
tools:tint="@color/icon_light" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/content_padding_standard"
android:layout_marginRight="@dimen/content_padding_standard"
android:layout_weight="1"
android:orientation="vertical">
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/list_item_title_text_size"
app:firstBaselineToTopHeight="25sp"
app:typeface="@string/font_roboto_regular"
tools:text="Some title" />
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="?android:attr/textColorSecondary"
android:textSize="@dimen/list_item_description_text_size"
app:firstBaselineToTopHeight="14sp"
app:lastBaselineToBottomHeight="16sp"
app:typeface="@string/font_roboto_regular"
tools:text="Some long description" />
</LinearLayout>
<Switch
android:id="@+id/switcher"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:background="@null"
android:clickable="false"
android:focusable="false" />
</LinearLayout>

View file

@ -186,6 +186,28 @@
</LinearLayout>
<LinearLayout
android:id="@+id/received_gps_points_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
tools:visibility="visible">
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/received_gps_points_description"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ellipsize="end"
android:maxLines="1"
android:textColor="?attr/android:textColorSecondary"
android:textSize="@dimen/list_item_description_text_size"
app:firstBaselineToTopHeight="@dimen/list_item_icon_margin_right"
app:typeface="@string/font_roboto_regular"
tools:text="@string/received_gps_points" />
</LinearLayout>
</LinearLayout>
<ImageView

View file

@ -128,87 +128,30 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="@dimen/content_padding_standard"
android:layout_marginRight="@dimen/content_padding_standard"
android:text="@string/turn_off_location_sharing"
android:textColor="?attr/ctrl_active_color"
android:textSize="@dimen/hint_text_size"
app:typeface="@string/font_roboto_medium" />
<LinearLayout
android:layout_width="match_parent"
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/expires_line"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
android:layout_gravity="center_vertical"
android:textColor="?android:attr/textColorSecondary"
android:textSize="@dimen/hint_text_size"
app:typeface="@string/font_roboto_regular"
tools:text="@string/expire_at" />
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/stop_in"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:textColor="?android:attr/textColorSecondary"
android:textSize="@dimen/hint_text_size"
app:typeface="@string/font_roboto_regular"
tools:text="@string/expire_at" />
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/ending_in_first_part"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:textColor="?android:attr/textColorPrimary"
android:textSize="@dimen/hint_text_size"
app:typeface="@string/font_roboto_mono_bold" />
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/ending_in_second_part"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:textColor="?android:attr/textColorSecondary"
android:textSize="@dimen/hint_text_size"
app:typeface="@string/font_roboto_regular" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/gps_points_line"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/gps_points"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:textColor="?android:attr/textColorSecondary"
android:textSize="@dimen/hint_text_size"
app:typeface="@string/font_roboto_regular"
android:text="@string/gps_points" />
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/gps_points_collected"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:textColor="?android:attr/textColorPrimary"
android:textSize="@dimen/hint_text_size"
app:typeface="@string/font_roboto_mono_bold" />
<net.osmand.telegram.ui.views.TextViewEx
android:layout_width="wrap_content"
android:id="@+id/gps_points_in_buffer_txt"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:textColor="?android:attr/textColorSecondary"
android:textSize="@dimen/hint_text_size"
android:text="@string/gps_points_in_buffer"
app:typeface="@string/font_roboto_regular" />
</LinearLayout>
android:layout_gravity="center_vertical"
android:text="@string/gps_points"
android:textColor="?android:attr/textColorSecondary"
android:textSize="@dimen/hint_text_size"
app:typeface="@string/font_roboto_regular" />
</LinearLayout>

View file

@ -15,7 +15,8 @@
<LinearLayout
android:id="@+id/main_view"
android:layout_width="match_parent"
android:layout_height="@dimen/list_item_height"
android:layout_height="wrap_content"
android:minHeight="@dimen/list_item_height"
android:layout_marginBottom="@dimen/list_item_bottom_margin"
android:background="?attr/selectableItemBackground"
android:gravity="center_vertical">
@ -106,6 +107,28 @@
</LinearLayout>
<LinearLayout
android:id="@+id/received_gps_points_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
tools:visibility="visible">
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/received_gps_points_description"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ellipsize="end"
android:maxLines="1"
android:textColor="?attr/android:textColorSecondary"
android:textSize="@dimen/list_item_description_text_size"
app:firstBaselineToTopHeight="@dimen/list_item_icon_margin_right"
app:typeface="@string/font_roboto_regular"
tools:text="@string/received_gps_points" />
</LinearLayout>
</LinearLayout>
<CheckBox

View file

@ -24,6 +24,7 @@
<dimen name="dialog_welcome_title_top_margin">89dp</dimen>
<dimen name="list_header_height">48dp</dimen>
<dimen name="list_header_with_descr_height">42dp</dimen>
<dimen name="list_item_height">56dp</dimen>
<dimen name="list_item_height_min">48dp</dimen>
@ -82,7 +83,7 @@
<dimen name="hint_text_size">14sp</dimen>
<dimen name="list_item_title_text_size">16sp</dimen>
<dimen name="list_item_description_text_size">12sp</dimen>
<dimen name="list_item_description_text_size">13sp</dimen>
<dimen name="text_button_text_size">15sp</dimen>

View file

@ -1,4 +1,8 @@
<resources>
<string name="received_gps_points">Received GPX points: %1$s</string>
<string name="shared_string_appearance">Appearance</string>
<string name="show_gps_points">Show GPS points</string>
<string name="show_gps_points_descr">Show quantity of collected and sent GPS points.</string>
<string name="please_update_osmand">Please update OsmAnd to view data on the map</string>
<string name="shared_string_update">Update</string>
<string name="gps_points_in_buffer">sent (%1$d in buffer)</string>

View file

@ -15,6 +15,7 @@ import net.osmand.telegram.utils.OsmandApiUtils
import net.osmand.telegram.utils.OsmandFormatter
import net.osmand.telegram.utils.OsmandFormatter.MetricsConstants
import net.osmand.telegram.utils.OsmandFormatter.SpeedConstants
import net.osmand.telegram.utils.OsmandLocationUtils
import org.drinkless.td.libcore.telegram.TdApi
import org.json.JSONArray
import org.json.JSONException
@ -29,7 +30,7 @@ const val SHARE_DEVICES_KEY = "devices"
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 =
listOf(1 * 60L, 2 * 60L, 5 * 60L, 10 * 60L, 15 * 60L, 30 * 60L, 60 * 60L)
listOf(1 * 60L, 2 * 60L, 5 * 60L, 10 * 60L, 15 * 60L, 30 * 60L, 60 * 60L, 60*60*24L)
private val LOC_HISTORY_VALUES_SEC = listOf(
5 * 60L,
15 * 60L,
@ -40,7 +41,8 @@ private val LOC_HISTORY_VALUES_SEC = listOf(
5 * 60 * 60L,
8 * 60 * 60L,
12 * 60 * 60L,
24 * 60 * 60L
24 * 60 * 60L,
7*24 * 60 * 60L
)
const val SHARE_TYPE_MAP = "Map"
@ -82,6 +84,8 @@ private const val BATTERY_OPTIMISATION_ASKED = "battery_optimisation_asked"
private const val MONITORING_ENABLED = "monitoring_enabled"
private const val SHOW_GPS_POINTS = "show_gps_points"
private const val SHARING_INITIALIZATION_TIME = 60 * 2L // 2 minutes
private const val WAITING_TDLIB_TIME = 30 // 2 seconds
@ -119,6 +123,8 @@ class TelegramSettings(private val app: TelegramApplication) {
var monitoringEnabled = false
var showGpsPoints = false
init {
updatePrefs()
read()
@ -259,7 +265,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)
val isOsmAndBot = app.telegramHelper.isOsmAndBot(OsmandLocationUtils.getSenderMessageId(message)) || app.telegramHelper.isOsmAndBot(message.viaBotUserId)
if (shareInfo != null) {
when (content) {
is TdApi.MessageLocation -> {
@ -513,6 +519,8 @@ class TelegramSettings(private val app: TelegramApplication) {
edit.putBoolean(MONITORING_ENABLED, monitoringEnabled)
edit.putBoolean(SHOW_GPS_POINTS, showGpsPoints)
val jArray = convertShareChatsInfoToJson()
if (jArray != null) {
edit.putString(SHARE_CHATS_INFO_KEY, jArray.toString())
@ -572,6 +580,8 @@ class TelegramSettings(private val app: TelegramApplication) {
batteryOptimisationAsked = prefs.getBoolean(BATTERY_OPTIMISATION_ASKED,false)
monitoringEnabled = prefs.getBoolean(MONITORING_ENABLED,false)
showGpsPoints = prefs.getBoolean(SHOW_GPS_POINTS,false)
}
private fun convertShareDevicesToJson():JSONObject?{

View file

@ -56,6 +56,10 @@ class LocationMessages(val app: TelegramApplication) {
return dbHelper.getIngoingUserLocations(start, end)
}
fun getIngoingUserLocationsInChat(userId: Int, chatId: Long, deviceName: String, start: Long, end: Long): UserLocations? {
return dbHelper.getIngoingUserLocationsInChat(userId, chatId, deviceName, start, end)
}
fun getMessagesForUserInChat(userId: Int, chatId: Long, deviceName: String, start: Long, end: Long): List<LocationMessage> {
return dbHelper.getMessagesForUserInChat(userId, chatId,deviceName, start, end)
}
@ -77,9 +81,9 @@ class LocationMessages(val app: TelegramApplication) {
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 newItem = LocationHistoryPoint(OsmandLocationUtils.getSenderMessageId(message), message.chatId, type, deviceName)
val previousMessageLatLon = lastLocationPoints[newItem]
val locationMessage = OsmandLocationUtils.createLocationMessage(message, app.telegramHelper, content, previousMessageLatLon)
val locationMessage = OsmandLocationUtils.createLocationMessage(message, content, previousMessageLatLon)
if (locationMessage != null) {
dbHelper.addLocationMessage(locationMessage)
lastLocationPoints[newItem] = LatLon(locationMessage.lat, locationMessage.lon)
@ -219,6 +223,35 @@ class LocationMessages(val app: TelegramApplication) {
return res
}
internal fun getIngoingUserLocationsInChat(userId: Int, chatId: Long, deviceName: String,start: Long, end: Long): UserLocations? {
val userLocationsMap: MutableMap<Int, MutableList<UserTrkSegment>> = mutableMapOf()
val userLocations = UserLocations(userId,chatId,deviceName,userLocationsMap)
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 = ? $whereDeviceQuery AND $COL_TIME BETWEEN $start AND $end ORDER BY $COL_TYPE DESC, $COL_TIME ", args)?.apply {
if (moveToFirst()) {
var segment: UserTrkSegment? = null
do {
val locationMessage = readLocationMessage(this@apply)
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<UserTrkSegment>()
}
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()
}
return userLocations
}
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 ""

View file

@ -84,7 +84,7 @@ class ShowLocationHelper(private val app: TelegramApplication) {
if (chatTitle != null && (content is TdApi.MessageLocation || (content is MessageUserLocation && content.isValid()))) {
var userName = ""
var photoPath: String? = null
val user = telegramHelper.getUser(message.senderUserId)
val user = telegramHelper.getUser(OsmandLocationUtils.getSenderMessageId(message))
if (user != null) {
userName = "${user.firstName} ${user.lastName}".trim()
if (userName.isEmpty()) {
@ -100,7 +100,7 @@ class ShowLocationHelper(private val app: TelegramApplication) {
}
}
if (userName.isEmpty()) {
userName = message.senderUserId.toString()
userName = OsmandLocationUtils.getSenderMessageId(message).toString()
}
setupMapLayer()
val params = generatePointParams(photoPath, stale)
@ -111,10 +111,10 @@ class ShowLocationHelper(private val app: TelegramApplication) {
}
if (aLatLon != null) {
if (update) {
osmandAidlHelper.updateMapPoint(MAP_LAYER_ID, "${chatId}_${message.senderUserId}", userName, userName,
osmandAidlHelper.updateMapPoint(MAP_LAYER_ID, "${chatId}_${OsmandLocationUtils.getSenderMessageId(message)}", userName, userName,
chatTitle, Color.WHITE, aLatLon, null, params)
} else {
osmandAidlHelper.addMapPoint(MAP_LAYER_ID, "${chatId}_${message.senderUserId}", userName, userName,
osmandAidlHelper.addMapPoint(MAP_LAYER_ID, "${chatId}_${OsmandLocationUtils.getSenderMessageId(message)}", userName, userName,
chatTitle, Color.WHITE, aLatLon, null, params)
}
}
@ -148,7 +148,7 @@ class ShowLocationHelper(private val app: TelegramApplication) {
fun hideMessages(messages: List<TdApi.Message>) {
osmandAidlHelper.execOsmandApi {
for (message in messages) {
val user = telegramHelper.getUser(message.senderUserId)
val user = telegramHelper.getUser(OsmandLocationUtils.getSenderMessageId(message))
if (user != null) {
removeMapPoint(message.chatId, message)
}
@ -277,7 +277,7 @@ class ShowLocationHelper(private val app: TelegramApplication) {
private fun removeMapPoint(chatId: Long, message: TdApi.Message) {
val content = message.content
if (content is TdApi.MessageLocation || content is MessageUserLocation) {
osmandAidlHelper.removeMapPoint(MAP_LAYER_ID, "${chatId}_${message.senderUserId}")
osmandAidlHelper.removeMapPoint(MAP_LAYER_ID, "${chatId}_${OsmandLocationUtils.getSenderMessageId(message)}")
} else if (content is MessageOsmAndBotLocation) {
osmandAidlHelper.removeMapPoint(MAP_LAYER_ID, "${chatId}_${content.deviceName}")
}

View file

@ -39,7 +39,7 @@ class TelegramHelper private constructor() {
const val MIN_LOCATION_MESSAGE_LIVE_PERIOD_SEC = 61
const val MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC = 60 * 60 * 24 - 1 // one day
const val MAX_LOCATION_MESSAGE_HISTORY_SCAN_SEC = 60 * 60 * 24 // one day
const val MAX_LOCATION_MESSAGE_HISTORY_SCAN_SEC = 7 * 60 * 60 * 24 // one day
private var helper: TelegramHelper? = null
@ -146,7 +146,7 @@ class TelegramHelper private constructor() {
fun getCurrentUserId() = currentUser?.id ?: -1
fun getUserMessage(user: TdApi.User) =
usersLocationMessages.values.firstOrNull { it.senderUserId == user.id }
usersLocationMessages.values.firstOrNull { OsmandLocationUtils.getSenderMessageId(it) == user.id }
fun getChatMessages(chatId: Long) =
usersLocationMessages.values.filter { it.chatId == chatId }
@ -348,15 +348,6 @@ class TelegramHelper private constructor() {
fun isBot(userId: Int) = users[userId]?.type is TdApi.UserTypeBot
fun getSenderMessageId(message: TdApi.Message): Int {
val forwardInfo = message.forwardInfo
return if (forwardInfo != null && forwardInfo is TdApi.MessageForwardedFromUser) {
forwardInfo.senderUserId
} else {
message.senderUserId
}
}
fun startLiveMessagesUpdates(interval: Long) {
stopLiveMessagesUpdates()
@ -678,18 +669,19 @@ class TelegramHelper private constructor() {
lastTelegramUpdateTime = Math.max(lastTelegramUpdateTime, Math.max(message.date, message.editDate))
if (message.isAppropriate()) {
log.debug("addNewMessage: ${message.id}")
val fromBot = isOsmAndBot(message.senderUserId)
val fromBot = isOsmAndBot(OsmandLocationUtils.getSenderMessageId(message))
val viaBot = isOsmAndBot(message.viaBotUserId)
if (message.isOutgoing && !fromBot && !viaBot) {
return
}
removeOldMessages(message, fromBot, viaBot)
val oldMessage = usersLocationMessages.values.firstOrNull {
getSenderMessageId(it) == getSenderMessageId(message) && it.chatId == message.chatId
OsmandLocationUtils.getSenderMessageId(it) == OsmandLocationUtils.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) {
message.content = OsmandLocationUtils.parseMessageContent(message, this)
usersLocationMessages[message.id] = message
}
if (message.isOutgoing) {
@ -713,7 +705,7 @@ class TelegramHelper private constructor() {
while (iterator.hasNext()) {
val message = iterator.next().value
if (newMessage.chatId == message.chatId) {
val sameSender = getSenderMessageId(newMessage) == getSenderMessageId(message)
val sameSender = OsmandLocationUtils.getSenderMessageId(newMessage) == OsmandLocationUtils.getSenderMessageId(message)
val viaSameBot = newMessage.viaBotUserId == message.viaBotUserId
if (fromBot || viaBot) {
if ((fromBot && sameSender) || (viaBot && viaSameBot)) {
@ -1091,7 +1083,7 @@ class TelegramHelper private constructor() {
}
val content = content
val isUserTextLocation = (content is TdApi.MessageText) && content.text.text.startsWith(USER_TEXT_LOCATION_TITLE)
val isOsmAndBot = isOsmAndBot(senderUserId) || isOsmAndBot(viaBotUserId)
val isOsmAndBot = isOsmAndBot(OsmandLocationUtils.getSenderMessageId(this)) || isOsmAndBot(viaBotUserId)
if (!(isUserTextLocation || content is TdApi.MessageLocation || isOsmAndBot)) {
return false
}

View file

@ -153,7 +153,7 @@ object TelegramUiHelper {
chat: TdApi.Chat,
message: TdApi.Message
): LocationItem? {
val user = helper.getUser(message.senderUserId) ?: return null
val user = helper.getUser(OsmandLocationUtils.getSenderMessageId(message)) ?: return null
val content = OsmandLocationUtils.parseMessageContent(message, helper)
return LocationItem().apply {
chatId = chat.id
@ -167,7 +167,7 @@ object TelegramUiHelper {
photoPath = helper.getUserPhotoPath(user)
grayscalePhotoPath = helper.getUserGreyPhotoPath(user)
placeholderId = R.drawable.img_user_picture
userId = message.senderUserId
userId = OsmandLocationUtils.getSenderMessageId(message)
lastUpdated = OsmandLocationUtils.getLastUpdatedTime(message)
}
}
@ -199,7 +199,7 @@ object TelegramUiHelper {
chat: TdApi.Chat,
message: TdApi.Message
): ChatItem? {
val user = helper.getUser(message.senderUserId) ?: return null
val user = helper.getUser(OsmandLocationUtils.getSenderMessageId(message)) ?: return null
val content = OsmandLocationUtils.parseMessageContent(message, helper)
return ChatItem().apply {
chatId = chat.id
@ -218,7 +218,7 @@ object TelegramUiHelper {
}
grayscalePhotoPath = helper.getUserGreyPhotoPath(user)
placeholderId = R.drawable.img_user_picture
userId = message.senderUserId
userId = OsmandLocationUtils.getSenderMessageId(message)
privateChat = helper.isPrivateChat(chat) || helper.isSecretChat(chat)
chatWithBot = helper.isBot(userId)
lastUpdated = OsmandLocationUtils.getLastUpdatedTime(message)

View file

@ -104,6 +104,7 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
mainView.findViewById<SwipeRefreshLayout>(R.id.swipe_refresh).apply {
setOnRefreshListener {
app.shareLocationHelper.checkNetworkType()
app.telegramHelper.scanChatsHistory()
updateList()
isRefreshing = false
}
@ -482,6 +483,13 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
holder.lastTelegramUpdateTime?.visibility = View.GONE
}
if (settings.showGpsPoints) {
holder.receivedGpxPointsContainer?.visibility = View.VISIBLE
holder.receivedGpxPointsDescr?.text = getChatItemGpxPointsDescription(item)
} else {
holder.receivedGpxPointsContainer?.visibility = View.GONE
}
if (item is ChatItem && holder is ChatViewHolder) {
val nextIsLocation = !lastItem && (items[position + 1] is LocationItem || !sortByGroup)
val chatId = item.chatId
@ -497,6 +505,13 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
holder.groupDescrContainer?.visibility = View.GONE
}
if (settings.showGpsPoints) {
holder.receivedGpxPointsContainer?.visibility = View.VISIBLE
holder.receivedGpxPointsDescr?.text = getChatItemGpxPointsDescription(item)
} else {
holder.receivedGpxPointsContainer?.visibility = View.GONE
}
holder.description?.text = getChatItemDescription(item)
holder.imageButton?.visibility = View.GONE
holder.showOnMapRow?.setOnClickListener { showPopupMenu(holder, chatId) }
@ -505,6 +520,12 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
holder.topDivider?.visibility = if (!sortByGroup && position != 0) View.GONE else View.VISIBLE
} else if (item is LocationItem && holder is ContactViewHolder) {
holder.description?.text = OsmandFormatter.getListItemLiveTimeDescr(app, item.lastUpdated, lastResponseStr)
if (settings.showGpsPoints) {
holder.receivedGpxPointsContainer?.visibility = View.VISIBLE
holder.receivedGpxPointsDescr?.text = getChatItemGpxPointsDescription(item)
} else {
holder.receivedGpxPointsContainer?.visibility = View.GONE
}
}
}
@ -533,6 +554,51 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
}
}
private fun getChatItemGpxPointsDescription(item: ListItem): String {
return when {
item is ChatItem && item.chatWithBot -> {
if (settings.liveNowSortType.isSortByGroup()) {
getString(R.string.shared_string_bot)
} else {
val deviceName = if(item.chatWithBot) item.name else ""
val start = System.currentTimeMillis() - settings.locHistoryTime * 1000
val end = System.currentTimeMillis()
val userLocations = app.locationMessages.getIngoingUserLocationsInChat(item.userId, item.chatId,deviceName,start, end)
var points = 0
userLocations?.getUniqueSegments()?.forEach { points += it.points.size }
getString(R.string.received_gps_points, points)
}
}
item is ChatItem && item.privateChat -> {
val deviceName = if(item.chatWithBot) item.name else ""
val start = System.currentTimeMillis() - settings.locHistoryTime * 1000
val end = System.currentTimeMillis()
val userLocations = app.locationMessages.getIngoingUserLocationsInChat(item.userId, item.chatId,deviceName,start, end)
var points = 0
userLocations?.getUniqueSegments()?.forEach { points += it.points.size }
getString(R.string.received_gps_points, points)
}
else -> {
if (!settings.liveNowSortType.isSortByGroup()&&item is ChatItem) {
val deviceName = if(item.chatWithBot) item.name else ""
val start = System.currentTimeMillis() - settings.locHistoryTime * 1000
val end = System.currentTimeMillis()
val userLocations = app.locationMessages.getIngoingUserLocationsInChat(item.userId, item.chatId,deviceName,start, end)
var points = 0
userLocations?.getUniqueSegments()?.forEach { points += it.points.size }
getString(R.string.received_gps_points, points)
} else {
val start = System.currentTimeMillis() - settings.locHistoryTime * 1000
val end = System.currentTimeMillis()
val userLocations = app.locationMessages.getIngoingUserLocationsInChat(item.userId, item.chatId,"",start, end)
var points = 0
userLocations?.getUniqueSegments()?.forEach { points += it.points.size }
getString(R.string.received_gps_points, points)
}
}
}
}
private fun showPopupMenu(holder: ChatViewHolder, chatId: Long) {
val ctx = holder.itemView.context
@ -584,6 +650,8 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
val directionIcon: ImageView? = view.findViewById(R.id.direction_icon)
val distanceText: TextView? = view.findViewById(R.id.distance_text)
val description: TextView? = view.findViewById(R.id.description)
val receivedGpxPointsContainer: View? = view.findViewById(R.id.received_gps_points_container)
val receivedGpxPointsDescr: TextView? = view.findViewById(R.id.received_gps_points_description)
val bottomShadow: View? = view.findViewById(R.id.bottom_shadow)
val lastTelegramUpdateTime: TextView? = view.findViewById(R.id.last_telegram_update_time)

View file

@ -13,15 +13,21 @@ import android.support.v4.content.ContextCompat
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.text.SpannableString
import android.text.SpannableStringBuilder
import android.text.style.ForegroundColorSpan
import android.view.*
import android.view.animation.LinearInterpolator
import android.widget.*
import net.osmand.telegram.*
import net.osmand.telegram.ADDITIONAL_ACTIVE_TIME_VALUES_SEC
import net.osmand.telegram.R
import net.osmand.telegram.SHARE_TYPE_MAP
import net.osmand.telegram.TelegramApplication
import net.osmand.telegram.helpers.FontCache
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
import net.osmand.telegram.ui.views.CustomTypefaceSpan
import net.osmand.telegram.utils.AndroidUtils
import net.osmand.telegram.utils.OsmandFormatter
import org.drinkless.td.libcore.telegram.TdApi
@ -695,45 +701,43 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
}
}
holder.stopSharingDescr?.apply {
visibility = getStopSharingVisibility(expiresIn)
text = getText(R.string.expire_at)
}
holder.stopSharingFirstPart?.apply {
visibility = getStopSharingVisibility(expiresIn)
text = OsmandFormatter.getFormattedTime(expiresIn * 1000)
}
holder.stopSharingSecondPart?.apply {
visibility = getStopSharingVisibility(expiresIn)
text = "(${getString(
R.string.in_time,
OsmandFormatter.getFormattedDuration(context!!, expiresIn, true)
)})"
}
holder.gpsPointsCollected?.apply {
if (shareInfo != null) {
text = " ${shareInfo.sentMessages}"
holder.sharingExpiresLine?.apply {
visibility = if (expiresIn > 0) View.VISIBLE else View.GONE
val description = SpannableStringBuilder(getText(R.string.expire_at))
val typeface = FontCache.getRobotoMonoBold(app)
val start = description.length
description.append(" ${OsmandFormatter.getFormattedTime(expiresIn * 1000)} ")
if (typeface != null) {
description.setSpan(CustomTypefaceSpan(typeface), start, description.length, 0)
}
description.setSpan(ForegroundColorSpan(ContextCompat.getColor(app, R.color.primary_text_light)), start, description.length, 0)
description.append((getString(R.string.in_time, OsmandFormatter.getFormattedDuration(context!!, expiresIn, true))))
text = description
}
holder.gpsPointsSent?.apply {
holder.gpsPointsLine?.apply {
visibility = if (app.settings.showGpsPoints && shareInfo != null) View.VISIBLE else View.GONE
if (shareInfo != null) {
val bufferedPoints =
if (app.settings.shareTypeValue == SHARE_TYPE_MAP_AND_TEXT || app.settings.shareTypeValue == SHARE_TYPE_TEXT) {
shareInfo.pendingTdLibText + app.locationMessages.getBufferedMessagesCountForChat(shareInfo.chatId, LocationMessages.TYPE_TEXT)
} else {
shareInfo.pendingTdLibMap + app.locationMessages.getBufferedMessagesCountForChat(shareInfo.chatId, LocationMessages.TYPE_MAP)
}
text = getString(R.string.gps_points_in_buffer, bufferedPoints)
val description = SpannableStringBuilder(getText(R.string.gps_points))
val typeface = FontCache.getRobotoMonoBold(app)
val bufferedPoints = if (app.settings.shareTypeValue == SHARE_TYPE_MAP) {
shareInfo.pendingTdLibMap + app.locationMessages.getBufferedMessagesCountForChat(shareInfo.chatId, LocationMessages.TYPE_MAP)
} else {
shareInfo.pendingTdLibText + app.locationMessages.getBufferedMessagesCountForChat(shareInfo.chatId, LocationMessages.TYPE_TEXT)
}
val start = description.length
description.append(" ${shareInfo.sentMessages} ")
if (typeface != null) {
description.setSpan(CustomTypefaceSpan(typeface), start, description.length, 0)
}
description.setSpan(ForegroundColorSpan(ContextCompat.getColor(app, R.color.primary_text_light)), start, description.length, 0)
description.append(getString(R.string.gps_points_in_buffer, bufferedPoints))
text = description
}
}
}
}
private fun getStopSharingVisibility(expiresIn: Long) =
if (expiresIn > 0) View.VISIBLE else View.GONE
private fun removeItem(chat: TdApi.Object) {
items.remove(chat)
if (items.isEmpty()) {
@ -762,11 +766,8 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
inner class SharingChatViewHolder(val view: View) : BaseViewHolder(view) {
val descriptionDuration: TextView? = view.findViewById(R.id.duration)
val switcher: Switch? = view.findViewById(R.id.switcher)
val stopSharingDescr: TextView? = view.findViewById(R.id.stop_in)
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_in_buffer_txt)
val sharingExpiresLine: TextView? = view.findViewById(R.id.expires_line)
val gpsPointsLine: TextView? = view.findViewById(R.id.gps_points_line)
}
}

View file

@ -75,6 +75,22 @@ class SettingsDialogFragment : BaseDialogFragment() {
}
}
container = mainView.findViewById<ViewGroup>(R.id.gps_points_container)
inflater.inflate(R.layout.item_with_descr_and_right_switch, container, false).apply {
findViewById<ImageView>(R.id.icon).setImageDrawable(uiUtils.getThemedIcon(R.drawable.ic_action_connect))
findViewById<TextView>(R.id.title).text = getText(R.string.show_gps_points)
findViewById<TextView>(R.id.description).text = getText(R.string.show_gps_points_descr)
val switcher = findViewById<Switch>(R.id.switcher).apply {
isChecked = app.settings.showGpsPoints
}
setOnClickListener {
val checked = !app.settings.showGpsPoints
app.settings.showGpsPoints = checked
switcher.isChecked = checked
}
container.addView(this)
}
shareAsDescription = mainView.findViewById<TextView>(R.id.share_as_description).apply {
text = getText(R.string.share_location_as_description)
setOnClickListener {

View file

@ -239,8 +239,9 @@ class TimelineTabFragment : Fragment() {
holder.locationAndDescrContainer?.visibility = View.GONE
holder.distanceAndPointsContainer?.visibility = View.VISIBLE
holder.distanceImage?.setImageDrawable(app.uiUtils.getThemedIcon(R.drawable.ic_action_distance_16dp))
val point = if (groupDescrRowVisible) "" else ""
holder.distanceAndPointsTitle?.text = "$distance (${getString(R.string.points_size, trackData.points)}) $point "
val bullet = if (groupDescrRowVisible) "" else ""
val points = if (app.settings.showGpsPoints) "(${getString(R.string.points_size, trackData.points)})" else ""
holder.distanceAndPointsTitle?.text = "$distance $points $bullet "
holder.userRow?.setOnClickListener {
childFragmentManager.also {
UserGpxInfoFragment.showInstance(it, item.userId, item.chatId, userLocations.deviceName ,trackData.minTime, trackData.maxTime)
@ -263,7 +264,7 @@ class TimelineTabFragment : Fragment() {
if (uiTrackData.minTime == 0L) {
uiTrackData.minTime = it.minTime
}
uiTrackData.dist += it.distance.toFloat();
uiTrackData.dist += it.distance.toFloat()
uiTrackData.points += it.points.size
uiTrackData.maxTime = it.maxTime
}

View file

@ -0,0 +1,21 @@
package net.osmand.telegram.ui.views
import android.graphics.Typeface
import android.text.TextPaint
import android.text.style.MetricAffectingSpan
class CustomTypefaceSpan(val font: Typeface) : MetricAffectingSpan() {
override fun updateMeasureState(textPaint: TextPaint) = update(textPaint)
override fun updateDrawState(textPaint: TextPaint) = update(textPaint)
private fun update(textPaint: TextPaint) {
textPaint.apply {
val old = typeface
val oldStyle = old?.style ?: 0
typeface = Typeface.create(font, oldStyle)
}
}
}

View file

@ -61,10 +61,11 @@ object OsmandLocationUtils {
if (message.replyMarkup is TdApi.ReplyMarkupInlineKeyboard) {
val replyMarkup = message.replyMarkup as TdApi.ReplyMarkupInlineKeyboard
try {
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) ?: ""
val content = message.content
when {
replyMarkup.rows[0].size > 1 -> deviceName = replyMarkup.rows[0][1].text.split("\\s".toRegex())[1]
content is TdApi.MessageText -> deviceName = content.text.text.lines().firstOrNull()?.removePrefix(DEVICE_PREFIX) ?: ""
content is MessageOsmAndBotLocation -> deviceName = content.deviceName
}
} catch (e: Exception) {
@ -89,13 +90,22 @@ object OsmandLocationUtils {
return res
}
fun getSenderMessageId(message: TdApi.Message): Int {
val forwardInfo = message.forwardInfo
return if (forwardInfo != null && forwardInfo is TdApi.MessageForwardedFromUser) {
forwardInfo.senderUserId
} else {
message.senderUserId
}
}
fun parseMessage(message: TdApi.Message, helper: TelegramHelper, previousMessageLatLon: LatLon?): LocationMessage? {
val parsedContent = parseMessageContent(message, helper)
return createLocationMessage(message, helper, parsedContent, previousMessageLatLon)
return createLocationMessage(message, parsedContent, previousMessageLatLon)
}
fun parseMessageContent(message: TdApi.Message, helper: TelegramHelper): MessageLocation? {
val senderUserId = helper.getSenderMessageId(message)
val senderUserId = getSenderMessageId(message)
val fromBot = helper.isOsmAndBot(senderUserId)
val viaBot = helper.isOsmAndBot(message.viaBotUserId)
return when (message.content) {
@ -106,11 +116,11 @@ object OsmandLocationUtils {
}
}
fun createLocationMessage(message: TdApi.Message, helper: TelegramHelper, content:MessageLocation?, previousMessageLatLon: LatLon?):LocationMessage?{
fun createLocationMessage(message: TdApi.Message, content:MessageLocation?, previousMessageLatLon: LatLon?):LocationMessage?{
if (content == null) {
return null
}
val senderUserId = helper.getSenderMessageId(message)
val senderUserId = 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 ""