diff --git a/OsmAnd-telegram/res/drawable-hdpi/ic_action_ruler_unit.png b/OsmAnd-telegram/res/drawable-hdpi/ic_action_ruler_unit.png new file mode 100755 index 0000000000..4e6d0b951b Binary files /dev/null and b/OsmAnd-telegram/res/drawable-hdpi/ic_action_ruler_unit.png differ diff --git a/OsmAnd-telegram/res/drawable-hdpi/ic_action_speed.png b/OsmAnd-telegram/res/drawable-hdpi/ic_action_speed.png new file mode 100644 index 0000000000..3d5efa1f9f Binary files /dev/null and b/OsmAnd-telegram/res/drawable-hdpi/ic_action_speed.png differ diff --git a/OsmAnd-telegram/res/drawable-hdpi/ic_world_globe_dark.png b/OsmAnd-telegram/res/drawable-hdpi/ic_world_globe_dark.png new file mode 100644 index 0000000000..0acdc07e7a Binary files /dev/null and b/OsmAnd-telegram/res/drawable-hdpi/ic_world_globe_dark.png differ diff --git a/OsmAnd-telegram/res/drawable-mdpi/ic_action_ruler_unit.png b/OsmAnd-telegram/res/drawable-mdpi/ic_action_ruler_unit.png new file mode 100755 index 0000000000..fe4ff58402 Binary files /dev/null and b/OsmAnd-telegram/res/drawable-mdpi/ic_action_ruler_unit.png differ diff --git a/OsmAnd-telegram/res/drawable-mdpi/ic_action_speed.png b/OsmAnd-telegram/res/drawable-mdpi/ic_action_speed.png new file mode 100644 index 0000000000..a6de19816e Binary files /dev/null and b/OsmAnd-telegram/res/drawable-mdpi/ic_action_speed.png differ diff --git a/OsmAnd-telegram/res/drawable-mdpi/ic_world_globe_dark.png b/OsmAnd-telegram/res/drawable-mdpi/ic_world_globe_dark.png new file mode 100644 index 0000000000..15554f2444 Binary files /dev/null and b/OsmAnd-telegram/res/drawable-mdpi/ic_world_globe_dark.png differ diff --git a/OsmAnd-telegram/res/drawable-xhdpi/ic_action_ruler_unit.png b/OsmAnd-telegram/res/drawable-xhdpi/ic_action_ruler_unit.png new file mode 100755 index 0000000000..f719f6b7ce Binary files /dev/null and b/OsmAnd-telegram/res/drawable-xhdpi/ic_action_ruler_unit.png differ diff --git a/OsmAnd-telegram/res/drawable-xhdpi/ic_action_speed.png b/OsmAnd-telegram/res/drawable-xhdpi/ic_action_speed.png new file mode 100644 index 0000000000..aa69a709a5 Binary files /dev/null and b/OsmAnd-telegram/res/drawable-xhdpi/ic_action_speed.png differ diff --git a/OsmAnd-telegram/res/drawable-xhdpi/ic_world_globe_dark.png b/OsmAnd-telegram/res/drawable-xhdpi/ic_world_globe_dark.png new file mode 100644 index 0000000000..0255f1b883 Binary files /dev/null and b/OsmAnd-telegram/res/drawable-xhdpi/ic_world_globe_dark.png differ diff --git a/OsmAnd-telegram/res/drawable-xxhdpi/ic_action_ruler_unit.png b/OsmAnd-telegram/res/drawable-xxhdpi/ic_action_ruler_unit.png new file mode 100755 index 0000000000..f7e4543506 Binary files /dev/null and b/OsmAnd-telegram/res/drawable-xxhdpi/ic_action_ruler_unit.png differ diff --git a/OsmAnd-telegram/res/drawable-xxhdpi/ic_action_speed.png b/OsmAnd-telegram/res/drawable-xxhdpi/ic_action_speed.png new file mode 100644 index 0000000000..8231d72e64 Binary files /dev/null and b/OsmAnd-telegram/res/drawable-xxhdpi/ic_action_speed.png differ diff --git a/OsmAnd-telegram/res/drawable-xxhdpi/ic_world_globe_dark.png b/OsmAnd-telegram/res/drawable-xxhdpi/ic_world_globe_dark.png new file mode 100644 index 0000000000..97d6b3b781 Binary files /dev/null and b/OsmAnd-telegram/res/drawable-xxhdpi/ic_world_globe_dark.png differ diff --git a/OsmAnd-telegram/res/drawable-xxxhdpi/ic_action_ruler_unit.png b/OsmAnd-telegram/res/drawable-xxxhdpi/ic_action_ruler_unit.png new file mode 100755 index 0000000000..2305e5f380 Binary files /dev/null and b/OsmAnd-telegram/res/drawable-xxxhdpi/ic_action_ruler_unit.png differ diff --git a/OsmAnd-telegram/res/layout/fragement_settings_dialog.xml b/OsmAnd-telegram/res/layout/fragement_settings_dialog.xml index 6b4af3e0e8..43c521ed2a 100644 --- a/OsmAnd-telegram/res/layout/fragement_settings_dialog.xml +++ b/OsmAnd-telegram/res/layout/fragement_settings_dialog.xml @@ -75,6 +75,35 @@ + + + + + + + + + + + Select time zone to show in your location messages. + Time zone + Units & formats + Change what distance is measured in. + Units of length + Define unit of speed. + Unit of speed Saved messages End Start diff --git a/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt b/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt index ac68e16384..71ae9f6215 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt @@ -11,9 +11,7 @@ import net.osmand.PlatformUtil import net.osmand.telegram.helpers.OsmandAidlHelper import net.osmand.telegram.helpers.ShowLocationHelper import net.osmand.telegram.helpers.TelegramHelper -import net.osmand.telegram.utils.AndroidUtils -import net.osmand.telegram.utils.OsmandApiUtils -import net.osmand.telegram.utils.OsmandFormatter +import net.osmand.telegram.utils.* import net.osmand.telegram.utils.OsmandFormatter.MetricsConstants import net.osmand.telegram.utils.OsmandFormatter.SpeedConstants import net.osmand.telegram.utils.OsmandLocationUtils @@ -72,6 +70,7 @@ private const val SHARING_MODE_KEY = "current_sharing_mode" private const val METRICS_CONSTANTS_KEY = "metrics_constants" private const val SPEED_CONSTANTS_KEY = "speed_constants" +private const val UTC_OFFSET_CONSTANTS_KEY = "utc_offset_constants" private const val SEND_MY_LOC_INTERVAL_KEY = "send_my_loc_interval" private const val STALE_LOC_TIME_KEY = "stale_loc_time" @@ -125,6 +124,7 @@ class TelegramSettings(private val app: TelegramApplication) { var metricsConstants = MetricsConstants.KILOMETERS_AND_METERS var speedConstants = SpeedConstants.KILOMETERS_PER_HOUR + var utcOffset = DataConstants.UTC_FORMAT var sendMyLocInterval = SEND_MY_LOC_VALUES_SEC[SEND_MY_LOC_DEFAULT_INDEX] var staleLocTime = STALE_LOC_VALUES_SEC[STALE_LOC_DEFAULT_INDEX] @@ -142,6 +142,7 @@ class TelegramSettings(private val app: TelegramApplication) { val gpsAndLocPrefs = listOf(SendMyLocPref(), StaleLocPref(), LocHistoryPref(), ShareTypePref()) val gpxLoggingPrefs = listOf(MinLocationDistance(), MinLocationAccuracy(), MinLocationSpeed()) + val unitsAndFormatsPrefs = listOf(UnitsOfSpeed(), UnitsOfLength(), UtcOffset()) var batteryOptimisationAsked = false @@ -606,6 +607,7 @@ class TelegramSettings(private val app: TelegramApplication) { edit.putString(METRICS_CONSTANTS_KEY, metricsConstants.name) edit.putString(SPEED_CONSTANTS_KEY, speedConstants.name) + edit.putString(UTC_OFFSET_CONSTANTS_KEY, utcOffset) edit.putLong(SEND_MY_LOC_INTERVAL_KEY, sendMyLocInterval) edit.putLong(STALE_LOC_TIME_KEY, staleLocTime) @@ -668,6 +670,7 @@ class TelegramSettings(private val app: TelegramApplication) { speedConstants = SpeedConstants.valueOf( prefs.getString(SPEED_CONSTANTS_KEY, SpeedConstants.KILOMETERS_PER_HOUR.name) ) + utcOffset = prefs.getString(UTC_OFFSET_CONSTANTS_KEY, DataConstants.UTC_FORMAT) try { parseShareChatsInfo(JSONArray(prefs.getString(SHARE_CHATS_INFO_KEY, ""))) @@ -895,68 +898,64 @@ class TelegramSettings(private val app: TelegramApplication) { } } - inner class SendMyLocPref : NumericPref( + inner class SendMyLocPref : ListPreference( R.drawable.ic_action_share_location, R.string.send_my_location, - R.string.send_my_location_desc, - SEND_MY_LOC_VALUES_SEC + R.string.send_my_location_desc ) { override fun getCurrentValue() = OsmandFormatter.getFormattedDuration(app, sendMyLocInterval) override fun setCurrentValue(index: Int) { - sendMyLocInterval = values[index].toLong() + sendMyLocInterval = SEND_MY_LOC_VALUES_SEC[index] app.updateSendLocationInterval() } override fun getMenuItems() = - values.map { OsmandFormatter.getFormattedDuration(app, it.toLong()) } + SEND_MY_LOC_VALUES_SEC.map { OsmandFormatter.getFormattedDuration(app, it) } } - inner class StaleLocPref : NumericPref( + inner class StaleLocPref : ListPreference( R.drawable.ic_action_time_span, R.string.stale_location, - R.string.stale_location_desc, - STALE_LOC_VALUES_SEC + R.string.stale_location_desc ) { override fun getCurrentValue() = OsmandFormatter.getFormattedDuration(app, staleLocTime) override fun setCurrentValue(index: Int) { - staleLocTime = values[index].toLong() + staleLocTime = STALE_LOC_VALUES_SEC[index] } override fun getMenuItems() = - values.map { OsmandFormatter.getFormattedDuration(app, it.toLong()) } + STALE_LOC_VALUES_SEC.map { OsmandFormatter.getFormattedDuration(app, it) } } - inner class LocHistoryPref : NumericPref( + inner class LocHistoryPref : ListPreference( R.drawable.ic_action_location_history, R.string.location_history, - R.string.location_history_desc, - LOC_HISTORY_VALUES_SEC + R.string.location_history_desc ) { override fun getCurrentValue() = OsmandFormatter.getFormattedDuration(app, locHistoryTime) override fun setCurrentValue(index: Int) { - val value = values[index] - locHistoryTime = value.toLong() - app.telegramHelper.messageActiveTimeSec = value.toLong() + val value = LOC_HISTORY_VALUES_SEC[index] + locHistoryTime = value + app.telegramHelper.messageActiveTimeSec = value } override fun getMenuItems() = - values.map { OsmandFormatter.getFormattedDuration(app, it.toLong()) } + LOC_HISTORY_VALUES_SEC.map { OsmandFormatter.getFormattedDuration(app, it) } } - inner class ShareTypePref : NumericPref( + inner class ShareTypePref : ListPreference( R.drawable.ic_action_location_history, R.string.send_location_as, - R.string.send_location_as_descr, - emptyList() + R.string.send_location_as_descr ) { override fun getCurrentValue(): String { @@ -988,20 +987,16 @@ class TelegramSettings(private val app: TelegramApplication) { } } - inner class MinLocationDistance : NumericPref( - 0, R.string.min_logging_distance, - R.string.min_logging_distance_descr, - MIN_LOCATION_DISTANCE - ) { + inner class MinLocationDistance : + ListPreference(0, R.string.min_logging_distance, R.string.min_logging_distance_descr) { override fun getCurrentValue() = getFormattedValue(minLocationDistance) override fun setCurrentValue(index: Int) { - val value = values[index] - minLocationDistance = value.toFloat() + minLocationDistance = MIN_LOCATION_DISTANCE[index] } - override fun getMenuItems() = values.map { getFormattedValue(it.toFloat()) } + override fun getMenuItems() = MIN_LOCATION_DISTANCE.map { getFormattedValue(it) } private fun getFormattedValue(value: Float): String { return if (value == 0f) app.getString(R.string.shared_string_select) @@ -1009,20 +1004,16 @@ class TelegramSettings(private val app: TelegramApplication) { } } - inner class MinLocationAccuracy : NumericPref( - 0, R.string.min_logging_accuracy, - R.string.min_logging_accuracy_descr, - MIN_LOCATION_ACCURACY - ) { + inner class MinLocationAccuracy : + ListPreference(0, R.string.min_logging_accuracy, R.string.min_logging_accuracy_descr) { override fun getCurrentValue() = getFormattedValue(minLocationAccuracy) override fun setCurrentValue(index: Int) { - val value = values[index] - minLocationAccuracy = value.toFloat() + minLocationAccuracy = MIN_LOCATION_ACCURACY[index] } - override fun getMenuItems() = values.map { getFormattedValue(it.toFloat()) } + override fun getMenuItems() = MIN_LOCATION_ACCURACY.map { getFormattedValue(it) } private fun getFormattedValue(value: Float): String { return if (value == 0f) app.getString(R.string.shared_string_select) @@ -1030,20 +1021,16 @@ class TelegramSettings(private val app: TelegramApplication) { } } - inner class MinLocationSpeed : NumericPref( - 0, R.string.min_logging_speed, - R.string.min_logging_speed_descr, - MIN_LOCATION_SPEED - ) { + inner class MinLocationSpeed : + ListPreference(0, R.string.min_logging_speed, R.string.min_logging_speed_descr) { override fun getCurrentValue() = getFormattedValue(minLocationSpeed) override fun setCurrentValue(index: Int) { - val value = values[index] - minLocationSpeed = value.toFloat() + minLocationSpeed = MIN_LOCATION_SPEED[index] } - override fun getMenuItems() = values.map { getFormattedValue(it.toFloat()) } + override fun getMenuItems() = MIN_LOCATION_SPEED.map { getFormattedValue(it) } private fun getFormattedValue(value: Float): String { return when (value) { @@ -1054,11 +1041,54 @@ class TelegramSettings(private val app: TelegramApplication) { } } - abstract inner class NumericPref( + inner class UnitsOfSpeed : ListPreference( + R.drawable.ic_action_speed, + R.string.unit_of_speed_system, + R.string.unit_of_speed_system_descr + ) { + + override fun getCurrentValue() = speedConstants.toShortString(app) + + override fun setCurrentValue(index: Int) { + speedConstants = SpeedConstants.values()[index] + } + + override fun getMenuItems() = SpeedConstants.values().map { it.toShortString(app) } + } + + inner class UnitsOfLength : ListPreference( + R.drawable.ic_action_ruler_unit, R.string.unit_of_length, + R.string.unit_of_length_descr + ) { + + override fun getCurrentValue() = metricsConstants.toHumanString(app) + + override fun setCurrentValue(index: Int) { + metricsConstants = MetricsConstants.values()[index] + } + + override fun getMenuItems() = MetricsConstants.values().map { it.toHumanString(app) } + } + + inner class UtcOffset : ListPreference( + R.drawable.ic_world_globe_dark, R.string.time_zone, + R.string.time_zone_descr + ) { + private val formattedUtcOffsets = DataConstants.utcOffsets.keys.toList() + + override fun getCurrentValue() = utcOffset + + override fun setCurrentValue(index: Int) { + utcOffset = formattedUtcOffsets[index] + } + + override fun getMenuItems() = formattedUtcOffsets + } + + abstract inner class ListPreference( @DrawableRes val iconId: Int, @StringRes val titleId: Int, - @StringRes val descriptionId: Int, - val values: List + @StringRes val descriptionId: Int ) { abstract fun getCurrentValue(): String diff --git a/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShareLocationHelper.kt b/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShareLocationHelper.kt index b45a185757..3c90c2a636 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShareLocationHelper.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShareLocationHelper.kt @@ -7,6 +7,7 @@ import net.osmand.telegram.helpers.LocationMessages.BufferMessage import net.osmand.telegram.notifications.TelegramNotification.NotificationType import net.osmand.telegram.utils.AndroidNetworkUtils import net.osmand.telegram.utils.BASE_URL +import net.osmand.telegram.utils.OsmandLocationUtils import net.osmand.util.MapUtils import org.drinkless.td.libcore.telegram.TdApi import org.json.JSONException @@ -14,8 +15,6 @@ import org.json.JSONObject private const val USER_SET_LIVE_PERIOD_DELAY_MS = 5000 // 5 sec -private const val UPDATE_LOCATION_ACCURACY = 150 // 150 meters - private const val SENT_LOCATIONS_INTERVAL_TIME_MS = 4000 // 4 sec class ShareLocationHelper(private val app: TelegramApplication) { @@ -142,7 +141,8 @@ class ShareLocationHelper(private val app: TelegramApplication) { if (it.deviceName.isEmpty()) { if (!shareInfo.pendingTextMessage && shareInfo.currentTextMessageId != -1L) { lastLocationSentTime = System.currentTimeMillis() - app.telegramHelper.editTextLocation(shareInfo, it) + val content = OsmandLocationUtils.getTextMessageContent(shareInfo.updateTextMessageId, it, app) + app.telegramHelper.editTextLocation(shareInfo, content) app.locationMessages.removeBufferedMessage(it) } } else { @@ -263,7 +263,8 @@ class ShareLocationHelper(private val app: TelegramApplication) { sendLocationToBot(message, shareInfo, SHARE_TYPE_TEXT) } else { lastLocationSentTime = System.currentTimeMillis() - app.telegramHelper.sendNewTextLocation(shareInfo, message) + val content = OsmandLocationUtils.getTextMessageContent(shareInfo.updateTextMessageId, message, app) + app.telegramHelper.sendNewTextLocation(shareInfo, content) } } } else { @@ -276,7 +277,8 @@ class ShareLocationHelper(private val app: TelegramApplication) { } else { if (shareInfo.pendingTdLibText < MAX_MESSAGES_IN_TDLIB_PER_CHAT) { lastLocationSentTime = System.currentTimeMillis() - app.telegramHelper.editTextLocation(shareInfo, message) + val content = OsmandLocationUtils.getTextMessageContent(shareInfo.updateTextMessageId, message, app) + app.telegramHelper.editTextLocation(shareInfo, content) } else { app.locationMessages.addBufferedMessage(message) } diff --git a/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramHelper.kt b/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramHelper.kt index 634621e268..6ee0d79c8e 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramHelper.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramHelper.kt @@ -926,9 +926,8 @@ class TelegramHelper private constructor() { } } - fun sendNewTextLocation(shareInfo: TelegramSettings.ShareChatInfo, location: LocationMessages.BufferMessage) { + fun sendNewTextLocation(shareInfo: TelegramSettings.ShareChatInfo, content: TdApi.InputMessageText) { shareInfo.updateTextMessageId = 1 - val content = OsmandLocationUtils.getTextMessageContent(shareInfo.updateTextMessageId, location) if (!shareInfo.pendingTextMessage) { shareInfo.pendingTextMessage = true shareInfo.pendingTdLibText++ @@ -940,8 +939,7 @@ class TelegramHelper private constructor() { } } - fun editTextLocation(shareInfo: TelegramSettings.ShareChatInfo, location: LocationMessages.BufferMessage) { - val content = OsmandLocationUtils.getTextMessageContent(shareInfo.updateTextMessageId, location) + fun editTextLocation(shareInfo: TelegramSettings.ShareChatInfo, content: TdApi.InputMessageText) { if (shareInfo.currentTextMessageId!=-1L) { shareInfo.pendingTdLibText++ shareInfo.lastSendTextMessageTime = (System.currentTimeMillis() / 1000).toInt() diff --git a/OsmAnd-telegram/src/net/osmand/telegram/ui/SettingsDialogFragment.kt b/OsmAnd-telegram/src/net/osmand/telegram/ui/SettingsDialogFragment.kt index a20a5a14e2..0b492bbcae 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/ui/SettingsDialogFragment.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/ui/SettingsDialogFragment.kt @@ -17,7 +17,7 @@ import android.view.ViewGroup import android.widget.* import net.osmand.telegram.R import net.osmand.telegram.TelegramSettings -import net.osmand.telegram.TelegramSettings.NumericPref +import net.osmand.telegram.TelegramSettings.ListPreference import net.osmand.telegram.helpers.TelegramHelper.Companion.OSMAND_BOT_USERNAME import net.osmand.telegram.helpers.TelegramUiHelper import net.osmand.telegram.utils.AndroidUtils @@ -50,7 +50,7 @@ class SettingsDialogFragment : BaseDialogFragment() { } var container = mainView.findViewById(R.id.gps_and_loc_container) settings.gpsAndLocPrefs.forEach { - createNumericPref(inflater, container, it) + createListPref(inflater, container, it) } if (Build.VERSION.SDK_INT >= 26) { @@ -66,6 +66,11 @@ class SettingsDialogFragment : BaseDialogFragment() { } } + container = mainView.findViewById(R.id.units_and_formats_container) + settings.unitsAndFormatsPrefs.forEach { + createListPref(inflater, container, it) + } + container = mainView.findViewById(R.id.gps_points_container) inflater.inflate(R.layout.item_with_descr_and_right_switch, container, false).apply { findViewById(R.id.icon).setImageDrawable(uiUtils.getThemedIcon(R.drawable.ic_action_connect)) @@ -139,7 +144,7 @@ class SettingsDialogFragment : BaseDialogFragment() { container = mainView.findViewById(R.id.gpx_settings_container) settings.gpxLoggingPrefs.forEach { - createNumericPref(inflater, container, it) + createListPref(inflater, container, it) } container = mainView.findViewById(R.id.osmand_connect_container) @@ -243,7 +248,7 @@ class SettingsDialogFragment : BaseDialogFragment() { } } - private fun createNumericPref(inflater: LayoutInflater, container: ViewGroup, pref: NumericPref) { + private fun createListPref(inflater: LayoutInflater, container: ViewGroup, pref: ListPreference) { inflater.inflate(R.layout.item_with_desc_and_right_value, container, false).apply { findViewById(R.id.icon).apply { if (pref.iconId != 0) { @@ -284,14 +289,14 @@ class SettingsDialogFragment : BaseDialogFragment() { } } - private fun showPopupMenu(pref: NumericPref, valueView: TextView) { + private fun showPopupMenu(pref: ListPreference, valueView: TextView) { val menuList = pref.getMenuItems() val ctx = valueView.context ListPopupWindow(ctx).apply { isModal = true anchorView = valueView setContentWidth(AndroidUtils.getPopupMenuWidth(ctx, menuList)) - height = if (menuList.size < 6) { + height = if (menuList.size <= 6) { ListPopupWindow.WRAP_CONTENT } else { AndroidUtils.getPopupMenuHeight(ctx) diff --git a/OsmAnd-telegram/src/net/osmand/telegram/utils/DataConstants.kt b/OsmAnd-telegram/src/net/osmand/telegram/utils/DataConstants.kt index 7532206e51..759dc9e2f1 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/utils/DataConstants.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/utils/DataConstants.kt @@ -2,6 +2,8 @@ package net.osmand.telegram.utils object DataConstants { + const val UTC_FORMAT = "UTC" + val countryPhoneCodes = mapOf("AB" to "+7840,+7940,+99544", "AF" to "+93", "AX" to "+35818", "AL" to "+355","DZ" to "+213", "AS" to "+1684", "AD" to "+376", "AO" to "+244","AI" to "+1264", "AG" to "+1268", "AR" to "+54", "AM" to "+374","AW" to "+297", "SH" to "+247", "AU" to "+61", @@ -44,4 +46,46 @@ object DataConstants { "TM" to "+993", "TC" to "+1649", "TV" to "+688", "UG" to "+256","UA" to "+380", "AE" to "+971", "UK" to "+44", "US" to "+1","UY" to "+598", "VI" to "+1340", "UZ" to "+998", "VU" to "+678", "VE" to "+58", "VA" to "+3906698,+379", "VN" to "+84", "WF" to "+681","YE" to "+967", "ZM" to "+260", "ZW" to "+263") + + val utcOffsets = mapOf( + "$UTC_FORMAT-12" to -12f, + "$UTC_FORMAT-11" to -11f, + "$UTC_FORMAT-10" to -10f, + "$UTC_FORMAT-09:30" to -9.5f, + "$UTC_FORMAT-9" to -9f, + "$UTC_FORMAT-8" to -8f, + "$UTC_FORMAT-7" to -7f, + "$UTC_FORMAT-6" to -6f, + "$UTC_FORMAT-5" to -5f, + "$UTC_FORMAT-4" to -4f, + "$UTC_FORMAT-03:30" to -3.5f, + "$UTC_FORMAT-3" to -3f, + "$UTC_FORMAT-2" to -2f, + "$UTC_FORMAT-1" to -1f, + UTC_FORMAT to 0f, + "$UTC_FORMAT+1" to 1f, + "$UTC_FORMAT+2" to 2f, + "$UTC_FORMAT+3" to 3f, + "$UTC_FORMAT+03:30" to 3.5f, + "$UTC_FORMAT+4" to 4f, + "$UTC_FORMAT+04:30" to 4.5f, + "$UTC_FORMAT+5" to 5f, + "$UTC_FORMAT+05:30" to 5.5f, + "$UTC_FORMAT+05:45" to 5.75f, + "$UTC_FORMAT+6" to 6f, + "$UTC_FORMAT+06:30" to 6.5f, + "$UTC_FORMAT+7" to 7f, + "$UTC_FORMAT+8" to 8f, + "$UTC_FORMAT+08:45" to 8.75f, + "$UTC_FORMAT+9" to 9f, + "$UTC_FORMAT+09:30" to 9.5f, + "$UTC_FORMAT+10" to 10f, + "$UTC_FORMAT+10:30" to 10.5f, + "$UTC_FORMAT+11" to 11f, + "$UTC_FORMAT+12" to 12f, + "$UTC_FORMAT+12:45" to 12.75f, + "$UTC_FORMAT+13" to 13f, + "$UTC_FORMAT+13:45" to 13.75f, + "$UTC_FORMAT+14" to 14f + ) } \ No newline at end of file diff --git a/OsmAnd-telegram/src/net/osmand/telegram/utils/OsmandFormatter.kt b/OsmAnd-telegram/src/net/osmand/telegram/utils/OsmandFormatter.kt index 3ca79e9867..b351a90efb 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/utils/OsmandFormatter.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/utils/OsmandFormatter.kt @@ -17,6 +17,14 @@ object OsmandFormatter { val YARDS_IN_ONE_METER = 1.0936f val FEET_IN_ONE_METER = YARDS_IN_ONE_METER * 3f + + val FORMAT_METERS_KEY = "m" + val FORMAT_FEET_KEY = "ft" + val FORMAT_YARDS_KEY = "yd" + val FORMAT_KILOMETERS_KEY = "km" + val FORMAT_NAUTICALMILES_KEY = "nmi" + val FORMAT_MILES_KEY = "mi" + private val fixed2 = DecimalFormat("0.00") private val fixed1 = DecimalFormat("0.0") @@ -166,118 +174,94 @@ object OsmandFormatter { } @JvmOverloads - fun getFormattedDistance(meters: Float, ctx: TelegramApplication, forceTrailingZeros: Boolean = true): String { + fun getFormattedDistance(meters: Float, ctx: TelegramApplication, forceTrailingZeros: Boolean = true, useLocalizedString: Boolean = true): String { val format1 = if (forceTrailingZeros) "{0,number,0.0} " else "{0,number,0.#} " val format2 = if (forceTrailingZeros) "{0,number,0.00} " else "{0,number,0.##} " val mc = ctx.settings.metricsConstants - val mainUnitStr: Int + val mainUnitStr: String val mainUnitInMeters: Float - if (mc == MetricsConstants.KILOMETERS_AND_METERS) { - mainUnitStr = R.string.km - mainUnitInMeters = METERS_IN_KILOMETER - } else if (mc == MetricsConstants.NAUTICAL_MILES) { - mainUnitStr = R.string.nm - mainUnitInMeters = METERS_IN_ONE_NAUTICALMILE - } else { - mainUnitStr = R.string.mile - mainUnitInMeters = METERS_IN_ONE_MILE + when (mc) { + MetricsConstants.KILOMETERS_AND_METERS -> { + mainUnitStr = if (useLocalizedString) ctx.getString(R.string.km) else FORMAT_KILOMETERS_KEY + mainUnitInMeters = METERS_IN_KILOMETER + } + MetricsConstants.NAUTICAL_MILES -> { + mainUnitStr = if (useLocalizedString) ctx.getString(R.string.nm) else FORMAT_NAUTICALMILES_KEY + mainUnitInMeters = METERS_IN_ONE_NAUTICALMILE + } + else -> { + mainUnitStr = if (useLocalizedString) ctx.getString(R.string.mile) else FORMAT_MILES_KEY + mainUnitInMeters = METERS_IN_ONE_MILE + } } if (meters >= 100 * mainUnitInMeters) { - return (meters / mainUnitInMeters + 0.5).toInt().toString() + " " + ctx.getString(mainUnitStr) //$NON-NLS-1$ + return (meters / mainUnitInMeters + 0.5).toInt().toString() + " " + mainUnitStr //$NON-NLS-1$ } else if (meters > 9.99f * mainUnitInMeters) { - return MessageFormat.format(format1 + ctx.getString(mainUnitStr), meters / mainUnitInMeters).replace('\n', ' ') //$NON-NLS-1$ + return MessageFormat.format(format1 + mainUnitStr, meters / mainUnitInMeters).replace('\n', ' ') //$NON-NLS-1$ } else if (meters > 0.999f * mainUnitInMeters) { - return MessageFormat.format(format2 + ctx.getString(mainUnitStr), meters / mainUnitInMeters).replace('\n', ' ') //$NON-NLS-1$ + return MessageFormat.format(format2 + mainUnitStr, meters / mainUnitInMeters).replace('\n', ' ') //$NON-NLS-1$ } else if (mc == MetricsConstants.MILES_AND_FEET && meters > 0.249f * mainUnitInMeters) { - return MessageFormat.format(format2 + ctx.getString(mainUnitStr), meters / mainUnitInMeters).replace('\n', ' ') //$NON-NLS-1$ + return MessageFormat.format(format2 + mainUnitStr, meters / mainUnitInMeters).replace('\n', ' ') //$NON-NLS-1$ } else if (mc == MetricsConstants.MILES_AND_METERS && meters > 0.249f * mainUnitInMeters) { - return MessageFormat.format(format2 + ctx.getString(mainUnitStr), meters / mainUnitInMeters).replace('\n', ' ') //$NON-NLS-1$ + return MessageFormat.format(format2 + mainUnitStr, meters / mainUnitInMeters).replace('\n', ' ') //$NON-NLS-1$ } else if (mc == MetricsConstants.MILES_AND_YARDS && meters > 0.249f * mainUnitInMeters) { - return MessageFormat.format(format2 + ctx.getString(mainUnitStr), meters / mainUnitInMeters).replace('\n', ' ') //$NON-NLS-1$ + return MessageFormat.format(format2 + mainUnitStr, meters / mainUnitInMeters).replace('\n', ' ') //$NON-NLS-1$ } else if (mc == MetricsConstants.NAUTICAL_MILES && meters > 0.99f * mainUnitInMeters) { - return MessageFormat.format(format2 + ctx.getString(mainUnitStr), meters / mainUnitInMeters).replace('\n', ' ') //$NON-NLS-1$ + return MessageFormat.format(format2 + mainUnitStr, meters / mainUnitInMeters).replace('\n', ' ') //$NON-NLS-1$ } else { if (mc == MetricsConstants.KILOMETERS_AND_METERS || mc == MetricsConstants.MILES_AND_METERS) { - return (meters + 0.5).toInt().toString() + " " + ctx.getString(R.string.m) //$NON-NLS-1$ + return (meters + 0.5).toInt().toString() + if (useLocalizedString) " " + ctx.getString(R.string.m) else " $FORMAT_METERS_KEY" //$NON-NLS-1$ } else if (mc == MetricsConstants.MILES_AND_FEET) { val feet = (meters * FEET_IN_ONE_METER + 0.5).toInt() - return feet.toString() + " " + ctx.getString(R.string.foot) //$NON-NLS-1$ + return feet.toString() + if (useLocalizedString) " " + ctx.getString(R.string.foot) else " $FORMAT_FEET_KEY" //$NON-NLS-1$ } else if (mc == MetricsConstants.MILES_AND_YARDS) { val yards = (meters * YARDS_IN_ONE_METER + 0.5).toInt() - return yards.toString() + " " + ctx.getString(R.string.yard) //$NON-NLS-1$ + return yards.toString() + if (useLocalizedString) " " + ctx.getString(R.string.yard) else " $FORMAT_YARDS_KEY" //$NON-NLS-1$ } - return (meters + 0.5).toInt().toString() + " " + ctx.getString(R.string.m) //$NON-NLS-1$ + return (meters + 0.5).toInt().toString() + if (useLocalizedString) " " + ctx.getString(R.string.m) else " $FORMAT_METERS_KEY" //$NON-NLS-1$ } } - fun getFormattedAlt(alt: Double, ctx: TelegramApplication): String { + fun getFormattedAlt(alt: Double, ctx: TelegramApplication, useLocalizedString: Boolean = true): String { val mc = ctx.settings.metricsConstants - return if (mc == MetricsConstants.KILOMETERS_AND_METERS) { - (alt + 0.5).toInt().toString() + " " + ctx.getString(R.string.m) + val useFeet = mc == MetricsConstants.MILES_AND_FEET || mc == MetricsConstants.MILES_AND_YARDS + return if (!useFeet) { + (alt + 0.5).toInt().toString() + if (useLocalizedString) " " + ctx.getString(R.string.m) else " $FORMAT_METERS_KEY" } else { - (alt * FEET_IN_ONE_METER + 0.5).toInt().toString() + " " + ctx.getString(R.string.foot) + (alt * FEET_IN_ONE_METER + 0.5).toInt().toString() + if (useLocalizedString) " " + ctx.getString(R.string.foot) else " $FORMAT_FEET_KEY" } } - fun getFormattedSpeed(metersperseconds: Float, ctx: TelegramApplication): String { + fun getFormattedSpeed(metersPerSeconds: Float, ctx: TelegramApplication, useLocalizedString: Boolean = true): String { val mc = ctx.settings.speedConstants - val kmh = metersperseconds * 3.6f - if (mc == SpeedConstants.KILOMETERS_PER_HOUR) { + val kmh = metersPerSeconds * 3.6f + val convertedSpeed: Float = when (mc) { + SpeedConstants.KILOMETERS_PER_HOUR -> kmh + SpeedConstants.MILES_PER_HOUR -> kmh * METERS_IN_KILOMETER / METERS_IN_ONE_MILE + SpeedConstants.NAUTICALMILES_PER_HOUR -> kmh * METERS_IN_KILOMETER / METERS_IN_ONE_NAUTICALMILE + SpeedConstants.MINUTES_PER_KILOMETER -> { + if (metersPerSeconds < 0.111111111) { + return "-" + if (useLocalizedString) mc.toShortString(ctx) else mc.getDefaultString() + } + METERS_IN_KILOMETER / (metersPerSeconds * 60) + } + SpeedConstants.MINUTES_PER_MILE -> { + if (metersPerSeconds < 0.111111111) { + return "-" + if (useLocalizedString) mc.toShortString(ctx) else mc.getDefaultString() + } + METERS_IN_ONE_MILE / (metersPerSeconds * 60) + } + else -> metersPerSeconds /*if (mc == SpeedConstants.METERS_PER_SECOND) */ + } + + return if (convertedSpeed >= mc.speedThreshold) { // e.g. car case and for high-speeds: Display rounded to 1 km/h (5% precision at 20 km/h) - if (kmh >= 20) { - return Math.round(kmh).toString() + " " + mc.toShortString(ctx) - } + "${Math.round(convertedSpeed)} " + if (useLocalizedString) mc.toShortString(ctx) else mc.getDefaultString() + } else { // for smaller values display 1 decimal digit x.y km/h, (0.5% precision at 20 km/h) - val kmh10 = Math.round(kmh * 10f) - return (kmh10 / 10f).toString() + " " + mc.toShortString(ctx) - } else if (mc == SpeedConstants.MILES_PER_HOUR) { - val mph = kmh * METERS_IN_KILOMETER / METERS_IN_ONE_MILE - if (mph >= 20) { - return Math.round(mph).toString() + " " + mc.toShortString(ctx) - } else { - val mph10 = Math.round(mph * 10f) - return (mph10 / 10f).toString() + " " + mc.toShortString(ctx) - } - } else if (mc == SpeedConstants.NAUTICALMILES_PER_HOUR) { - val mph = kmh * METERS_IN_KILOMETER / METERS_IN_ONE_NAUTICALMILE - if (mph >= 20) { - return Math.round(mph).toString() + " " + mc.toShortString(ctx) - } else { - val mph10 = Math.round(mph * 10f) - return (mph10 / 10f).toString() + " " + mc.toShortString(ctx) - } - } else if (mc == SpeedConstants.MINUTES_PER_KILOMETER) { - if (metersperseconds < 0.111111111) { - return "-" + mc.toShortString(ctx) - } - val minperkm = METERS_IN_KILOMETER / (metersperseconds * 60) - if (minperkm >= 10) { - return Math.round(minperkm).toString() + " " + mc.toShortString(ctx) - } else { - val mph10 = Math.round(minperkm * 10f) - return (mph10 / 10f).toString() + " " + mc.toShortString(ctx) - } - } else if (mc == SpeedConstants.MINUTES_PER_MILE) { - if (metersperseconds < 0.111111111) { - return "-" + mc.toShortString(ctx) - } - val minperm = METERS_IN_ONE_MILE / (metersperseconds * 60) - if (minperm >= 10) { - return Math.round(minperm).toString() + " " + mc.toShortString(ctx) - } else { - val mph10 = Math.round(minperm * 10f) - return (mph10 / 10f).toString() + " " + mc.toShortString(ctx) - } - } else - /*if (mc == SpeedConstants.METERS_PER_SECOND) */ { - if (metersperseconds >= 10) { - return Math.round(metersperseconds).toString() + " " + SpeedConstants.METERS_PER_SECOND.toShortString(ctx) - } - // for smaller values display 1 decimal digit x.y km/h, (0.5% precision at 20 km/h) - val kmh10 = Math.round(metersperseconds * 10f) - return (kmh10 / 10f).toString() + " " + SpeedConstants.METERS_PER_SECOND.toShortString(ctx) + "${Math.round(convertedSpeed * 10f) / 10f} " + if (useLocalizedString) mc.toShortString(ctx) else mc.getDefaultString() } } @@ -311,20 +295,27 @@ object OsmandFormatter { } } - enum class SpeedConstants private constructor(private val key: Int, private val descr: Int) { - KILOMETERS_PER_HOUR(R.string.km_h, R.string.si_kmh), - MILES_PER_HOUR(R.string.mile_per_hour, R.string.si_mph), - METERS_PER_SECOND(R.string.m_s, R.string.si_m_s), - MINUTES_PER_MILE(R.string.min_mile, R.string.si_min_m), - MINUTES_PER_KILOMETER(R.string.min_km, R.string.si_min_km), - NAUTICALMILES_PER_HOUR(R.string.nm_h, R.string.si_nm_h); + enum class SpeedConstants private constructor( + private val key: String, + private val title: Int, + private val descr: Int, + val speedThreshold: Int + ) { + KILOMETERS_PER_HOUR("km/h", R.string.km_h, R.string.si_kmh, 20), + MILES_PER_HOUR("mph", R.string.mile_per_hour, R.string.si_mph, 20), + METERS_PER_SECOND("m/s", R.string.m_s, R.string.si_m_s, 10), + MINUTES_PER_MILE("min/m", R.string.min_mile, R.string.si_min_m, 10), + MINUTES_PER_KILOMETER("min/km", R.string.min_km, R.string.si_min_km, 10), + NAUTICALMILES_PER_HOUR("nmi/h", R.string.nm_h, R.string.si_nm_h, 20); fun toHumanString(ctx: Context): String { return ctx.getString(descr) } fun toShortString(ctx: Context): String { - return ctx.getString(key) + return ctx.getString(title) } + + fun getDefaultString() = key } } diff --git a/OsmAnd-telegram/src/net/osmand/telegram/utils/OsmandLocationUtils.kt b/OsmAnd-telegram/src/net/osmand/telegram/utils/OsmandLocationUtils.kt index 8b585185dc..2f801fe17f 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/utils/OsmandLocationUtils.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/utils/OsmandLocationUtils.kt @@ -42,7 +42,9 @@ object OsmandLocationUtils { const val SECONDS_AGO_SUFFIX = " seconds ago" const val MINUTES_AGO_SUFFIX = " minutes ago" const val HOURS_AGO_SUFFIX = " hours ago" - const val UTC_FORMAT_SUFFIX = " UTC" + const val UTC_FORMAT_PATTERN = "yyyy-MM-dd HH:mm:ss" + + const val ONE_HOUR_TIME_MS = 60 * 60 * 1000 // 1 hour val UTC_DATE_FORMAT = SimpleDateFormat("yyyy-MM-dd", Locale.US).apply { timeZone = TimeZone.getTimeZone("UTC") @@ -163,9 +165,17 @@ object OsmandLocationUtils { return String.format(Locale.US, "%.5f, %.5f", sig.lat, sig.lon) } - fun formatFullTime(ti: Long): String { + fun formatFullTime(ti: Long, app: TelegramApplication): String { val dt = Date(ti) - return UTC_DATE_FORMAT.format(dt) + " " + UTC_TIME_FORMAT.format(dt) + " UTC" + val offsetKey = app.settings.utcOffset + val utcOffset = DataConstants.utcOffsets[offsetKey] ?: 0f + val simpleDateFormat = SimpleDateFormat(UTC_FORMAT_PATTERN, Locale.US) + + simpleDateFormat.timeZone = TimeZone.getTimeZone(DataConstants.UTC_FORMAT).apply { + rawOffset = (utcOffset * ONE_HOUR_TIME_MS).toInt() + } + + return "${simpleDateFormat.format(dt)} $offsetKey" } fun parseOsmAndBotLocationContent(oldContent: MessageOsmAndBotLocation, content: TdApi.MessageContent): MessageOsmAndBotLocation { @@ -242,21 +252,11 @@ object OsmandLocationUtils { } s.startsWith(ALTITUDE_PREFIX) -> { val altStr = s.removePrefix(ALTITUDE_PREFIX) - try { - val alt = altStr.split(" ").first() - res.altitude = alt.toDouble() - } catch (e: Exception) { - e.printStackTrace() - } + res.altitude = parseDistance(altStr) } s.startsWith(SPEED_PREFIX) -> { val speedStr = s.removePrefix(SPEED_PREFIX) - try { - val speed = speedStr.split(" ").first() - res.speed = speed.toDouble() - } catch (e: Exception) { - e.printStackTrace() - } + res.speed = parseSpeed(speedStr) } s.startsWith(BEARING_PREFIX) -> { val bearingStr = s.removePrefix(BEARING_PREFIX) @@ -269,12 +269,7 @@ object OsmandLocationUtils { } s.startsWith(HDOP_PREFIX) -> { val hdopStr = s.removePrefix(HDOP_PREFIX) - try { - val hdop = hdopStr.split(" ").first() - res.hdop = hdop.toDouble() - } catch (e: Exception) { - e.printStackTrace() - } + res.hdop = parseDistance(hdopStr) } s.startsWith(UPDATED_PREFIX) -> { if (res.lastUpdated == 0) { @@ -314,13 +309,19 @@ object OsmandLocationUtils { val hours = locStr.toLong() return (System.currentTimeMillis() - hours * 60 * 60 * 1000) } - timeS.endsWith(UTC_FORMAT_SUFFIX) -> { - val locStr = timeS.removeSuffix(UTC_FORMAT_SUFFIX) - val (latS, lonS) = locStr.split(" ") - val date = UTC_DATE_FORMAT.parse(latS) - val time = UTC_TIME_FORMAT.parse(lonS) - val res = date.time + time.time - return res + timeS.contains(DataConstants.UTC_FORMAT) -> { + val utcIndex = timeS.indexOf(DataConstants.UTC_FORMAT) + if (utcIndex != -1) { + val locStr = timeS.substring(0, utcIndex) + val utcOffset = timeS.substring(utcIndex) + val utcTimeOffset = DataConstants.utcOffsets[utcOffset] ?: 0f + val simpleDateFormat = SimpleDateFormat(UTC_FORMAT_PATTERN, Locale.US) + simpleDateFormat.timeZone = TimeZone.getTimeZone(DataConstants.UTC_FORMAT).apply { + rawOffset = (utcTimeOffset * ONE_HOUR_TIME_MS).toInt() + } + val res = simpleDateFormat.parse(locStr) + return res.time + } } } } catch (e: Exception) { @@ -329,50 +330,48 @@ object OsmandLocationUtils { return 0 } - fun getTextMessageContent(updateId: Int, location: LocationMessage): TdApi.InputMessageText { - val entities = mutableListOf() - val builder = StringBuilder() - val locationMessage = formatLocation(location) - - val firstSpace = USER_TEXT_LOCATION_TITLE.indexOf(' ') - val secondSpace = USER_TEXT_LOCATION_TITLE.indexOf(' ', firstSpace + 1) - entities.add(TdApi.TextEntity(builder.length + firstSpace + 1, secondSpace - firstSpace, TdApi.TextEntityTypeTextUrl(SHARING_LINK))) - builder.append("$USER_TEXT_LOCATION_TITLE\n") - - entities.add(TdApi.TextEntity(builder.lastIndex, LOCATION_PREFIX.length, TdApi.TextEntityTypeBold())) - builder.append(LOCATION_PREFIX) - - entities.add(TdApi.TextEntity(builder.length, locationMessage.length, - TdApi.TextEntityTypeTextUrl("$BASE_SHARING_URL?lat=${location.lat}&lon=${location.lon}"))) - builder.append("$locationMessage\n") - - if (location.altitude != 0.0) { - entities.add(TdApi.TextEntity(builder.lastIndex, ALTITUDE_PREFIX.length, TdApi.TextEntityTypeBold())) - builder.append(String.format(Locale.US, "$ALTITUDE_PREFIX%.1f m\n", location.altitude)) + fun parseSpeed(speedS: String): Double { + try { + if (!speedS.contains(" ")) { + return 0.0 + } + val speedSplit = speedS.split(" ") + val speedVal = speedSplit.first().toDouble() + val speedFormat = OsmandFormatter.SpeedConstants.values().firstOrNull { it.getDefaultString() == speedSplit.last() } + return when (speedFormat) { + OsmandFormatter.SpeedConstants.KILOMETERS_PER_HOUR -> speedVal / 3.6f + OsmandFormatter.SpeedConstants.MILES_PER_HOUR -> (speedVal / 3.6f) / (OsmandFormatter.METERS_IN_KILOMETER / OsmandFormatter.METERS_IN_ONE_MILE) + OsmandFormatter.SpeedConstants.NAUTICALMILES_PER_HOUR -> (speedVal / 3.6f) / (OsmandFormatter.METERS_IN_KILOMETER / OsmandFormatter.METERS_IN_ONE_NAUTICALMILE) + OsmandFormatter.SpeedConstants.MINUTES_PER_KILOMETER -> (OsmandFormatter.METERS_IN_KILOMETER / speedVal) / 60 + OsmandFormatter.SpeedConstants.MINUTES_PER_MILE -> (OsmandFormatter.METERS_IN_ONE_MILE / speedVal) / 60 + else -> speedVal + } + } catch (e: Exception) { + e.printStackTrace() } - if (location.speed > 0) { - entities.add(TdApi.TextEntity(builder.lastIndex, SPEED_PREFIX.length, TdApi.TextEntityTypeBold())) - builder.append(String.format(Locale.US, "$SPEED_PREFIX%.1f m/s\n", location.speed)) - } - if (location.bearing > 0) { - entities.add(TdApi.TextEntity(builder.lastIndex, BEARING_PREFIX.length, TdApi.TextEntityTypeBold())) - builder.append(String.format(Locale.US, "$BEARING_PREFIX%.1f$BEARING_SUFFIX\n", location.bearing)) - } - if (location.hdop != 0.0 && location.speed == 0.0) { - entities.add(TdApi.TextEntity(builder.lastIndex, HDOP_PREFIX.length, TdApi.TextEntityTypeBold())) - builder.append(String.format(Locale.US, "$HDOP_PREFIX%d m\n", location.hdop.toInt())) - } - if (updateId == 0) { - builder.append(String.format("$UPDATED_PREFIX%s\n", formatFullTime(location.time))) - } else { - builder.append(String.format("$UPDATED_PREFIX%s (%d)\n", formatFullTime(location.time), updateId)) - } - val textMessage = builder.toString().trim() - - return TdApi.InputMessageText(TdApi.FormattedText(textMessage, entities.toTypedArray()), true, true) + return 0.0 } - fun getTextMessageContent(updateId: Int, location: BufferMessage): TdApi.InputMessageText { + fun parseDistance(distanceS: String): Double { + try { + val distanceSplit = distanceS.split(" ") + val distanceVal = distanceSplit.first().toDouble() + return when (distanceSplit.last()) { + OsmandFormatter.FORMAT_METERS_KEY -> return distanceVal + OsmandFormatter.FORMAT_FEET_KEY -> return distanceVal / OsmandFormatter.FEET_IN_ONE_METER + OsmandFormatter.FORMAT_YARDS_KEY -> return distanceVal / OsmandFormatter.YARDS_IN_ONE_METER + OsmandFormatter.FORMAT_KILOMETERS_KEY -> return distanceVal * OsmandFormatter.METERS_IN_KILOMETER + OsmandFormatter.FORMAT_NAUTICALMILES_KEY -> return distanceVal * OsmandFormatter.METERS_IN_ONE_NAUTICALMILE + OsmandFormatter.FORMAT_MILES_KEY -> return distanceVal * OsmandFormatter.METERS_IN_ONE_MILE + else -> distanceVal + } + } catch (e: Exception) { + e.printStackTrace() + } + return 0.0 + } + + fun getTextMessageContent(updateId: Int, location: BufferMessage, app: TelegramApplication): TdApi.InputMessageText { val entities = mutableListOf() val builder = StringBuilder() val locationMessage = formatLocation(location) @@ -391,11 +390,13 @@ object OsmandLocationUtils { if (location.altitude != 0.0) { entities.add(TdApi.TextEntity(builder.lastIndex, ALTITUDE_PREFIX.length, TdApi.TextEntityTypeBold())) - builder.append(String.format(Locale.US, "$ALTITUDE_PREFIX%.1f m\n", location.altitude)) + val formattedAltitude = OsmandFormatter.getFormattedAlt(location.altitude, app, false) + builder.append(String.format(Locale.US, "$ALTITUDE_PREFIX%s\n", formattedAltitude)) } if (location.speed > 0) { entities.add(TdApi.TextEntity(builder.lastIndex, SPEED_PREFIX.length, TdApi.TextEntityTypeBold())) - builder.append(String.format(Locale.US, "$SPEED_PREFIX%.1f m/s\n", location.speed)) + val formattedSpeed = OsmandFormatter.getFormattedSpeed(location.speed.toFloat(), app, false) + builder.append(String.format(Locale.US, "$SPEED_PREFIX%s\n", formattedSpeed)) } if (location.bearing > 0) { entities.add(TdApi.TextEntity(builder.lastIndex, BEARING_PREFIX.length, TdApi.TextEntityTypeBold())) @@ -403,12 +404,13 @@ object OsmandLocationUtils { } if (location.hdop != 0.0 && location.speed == 0.0) { entities.add(TdApi.TextEntity(builder.lastIndex, HDOP_PREFIX.length, TdApi.TextEntityTypeBold())) - builder.append(String.format(Locale.US, "$HDOP_PREFIX%d m\n", location.hdop.toInt())) + val formattedHdop = OsmandFormatter.getFormattedDistance(location.hdop.toFloat(), app, false, false) + builder.append(String.format(Locale.US, "$HDOP_PREFIX%s\n", formattedHdop)) } if (updateId == 0) { - builder.append(String.format("$UPDATED_PREFIX%s\n", formatFullTime(location.time))) + builder.append(String.format("$UPDATED_PREFIX%s\n", formatFullTime(location.time, app))) } else { - builder.append(String.format("$UPDATED_PREFIX%s (%d)\n", formatFullTime(location.time), updateId)) + builder.append(String.format("$UPDATED_PREFIX%s (%d)\n", formatFullTime(location.time, app), updateId)) } val textMessage = builder.toString().trim() diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index b3a650da0e..01f6c91871 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -11,6 +11,7 @@ Thx - Hardy --> + Downloading %s Edit profiles Navigation type affects the rules for route calculations. %1$s • %2$s diff --git a/OsmAnd/src/net/osmand/plus/activities/DownloadTilesDialog.java b/OsmAnd/src/net/osmand/plus/activities/DownloadTilesDialog.java index 89035e5255..2ae1a58de7 100644 --- a/OsmAnd/src/net/osmand/plus/activities/DownloadTilesDialog.java +++ b/OsmAnd/src/net/osmand/plus/activities/DownloadTilesDialog.java @@ -123,7 +123,7 @@ public class DownloadTilesDialog { } final ProgressDialog progressDlg = new ProgressDialog(ctx); progressDlg.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); - progressDlg.setMessage(ctx.getString(R.string.shared_string_downloading) + ctx.getString(R.string.shared_string_ellipsis)); + progressDlg.setMessage(ctx.getString(R.string.shared_string_downloading)); progressDlg.setCancelable(true); progressDlg.setMax(numberTiles); progressDlg.setOnCancelListener(new DialogInterface.OnCancelListener(){ diff --git a/OsmAnd/src/net/osmand/plus/download/DownloadFileHelper.java b/OsmAnd/src/net/osmand/plus/download/DownloadFileHelper.java index 2aef38aa1f..36d2f21b85 100644 --- a/OsmAnd/src/net/osmand/plus/download/DownloadFileHelper.java +++ b/OsmAnd/src/net/osmand/plus/download/DownloadFileHelper.java @@ -263,13 +263,12 @@ public class DownloadFileHelper { mb = 1; } StringBuilder taskName = new StringBuilder(); - taskName.append(ctx.getString(R.string.shared_string_downloading)).append(": "); //+ de.baseName /*+ " " + mb + " MB"*/; taskName.append(FileNameTranslationHelper.getFileName(ctx, ctx.getRegions(), de.baseName)); if (de.type != null) { taskName.append(" ").append(de.type.getString(ctx)); } - progress.startTask(taskName.toString(), len / 1024); + progress.startTask(String.format(ctx.getString(R.string.shared_string_downloading_formatted), taskName.toString()), len / 1024); if (!de.zipStream) { copyFile(de, progress, fin, len, fin, de.fileToDownload); } else if(de.urlToDownload.contains(".gz")) { diff --git a/OsmAnd/src/net/osmand/plus/download/DownloadIndexesThread.java b/OsmAnd/src/net/osmand/plus/download/DownloadIndexesThread.java index e5db04a370..18f06cc21e 100644 --- a/OsmAnd/src/net/osmand/plus/download/DownloadIndexesThread.java +++ b/OsmAnd/src/net/osmand/plus/download/DownloadIndexesThread.java @@ -447,7 +447,7 @@ public class DownloadIndexesThread { mainView.setKeepScreenOn(true); } } - startTask(ctx.getString(R.string.shared_string_downloading) + ctx.getString(R.string.shared_string_ellipsis), -1); + startTask(ctx.getString(R.string.shared_string_downloading), -1); downloadHasStarted(); } diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelDownloadUpdateCard.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelDownloadUpdateCard.java index 9a3f67781b..5c24f944f3 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelDownloadUpdateCard.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/TravelDownloadUpdateCard.java @@ -109,7 +109,7 @@ public class TravelDownloadUpdateCard extends BaseTravelCard { @NonNull private String getTitle(boolean loading) { if (loading) { - return app.getString(R.string.shared_string_downloading) + "..."; + return app.getString(R.string.shared_string_downloading); } return app.getString(download ? R.string.download_file : R.string.update_is_available); }