diff --git a/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt b/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt index af994637bd..779586548d 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt @@ -1,6 +1,7 @@ package net.osmand.telegram import android.content.Context +import net.osmand.telegram.helpers.TelegramHelper import net.osmand.telegram.utils.OsmandFormatter.MetricsConstants import net.osmand.telegram.utils.OsmandFormatter.SpeedConstants @@ -18,10 +19,14 @@ private const val SEND_MY_LOCATION_INTERVAL_DEFAULT = 5L * 1000 // 5 seconds private const val USER_LOCATION_EXPIRE_TIME_KEY = "user_location_expire_time" private const val USER_LOCATION_EXPIRE_TIME_DEFAULT = 15L * 60 * 1000 // 15 minutes +private const val DEFAULT_VISIBLE_TIME_SECONDS = 60 * 60L // 1 hour + private const val TITLES_REPLACED_WITH_IDS = "changed_to_chat_id" class TelegramSettings(private val app: TelegramApplication) { + var chatLivePeriods = mutableMapOf() + private var shareLocationChats: Set = emptySet() private var showOnMapChats: Set = emptySet() @@ -52,20 +57,34 @@ class TelegramSettings(private val app: TelegramApplication) { val showOnMapChats = showOnMapChats.toMutableList() showOnMapChats.intersect(presentChatIds) this.showOnMapChats = showOnMapChats.toHashSet() + + chatLivePeriods = chatLivePeriods.filter { (key, _) -> + presentChatIds.contains(key) + }.toMutableMap() } - fun shareLocationToChat(chatId: Long, share: Boolean) { + fun shareLocationToChat(chatId: Long, share: Boolean, livePeriod: Long = DEFAULT_VISIBLE_TIME_SECONDS) { val shareLocationChats = shareLocationChats.toMutableList() if (share) { + val lp: Long = when { + livePeriod < TelegramHelper.MIN_LOCATION_MESSAGE_LIVE_PERIOD_SEC -> TelegramHelper.MIN_LOCATION_MESSAGE_LIVE_PERIOD_SEC.toLong() + livePeriod > TelegramHelper.MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC -> TelegramHelper.MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC.toLong() + else -> livePeriod + } + chatLivePeriods[chatId] = lp shareLocationChats.add(chatId) } else { shareLocationChats.remove(chatId) + chatLivePeriods.remove(chatId) } this.shareLocationChats = shareLocationChats.toHashSet() } + fun getChatLivePeriod(chatId: Long) = chatLivePeriods[chatId] + fun stopSharingLocationToChats() { this.shareLocationChats = emptySet() + this.chatLivePeriods.clear() } fun showChatOnMap(chatId: Long, show: Boolean) { diff --git a/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShareLocationHelper.kt b/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShareLocationHelper.kt index 84b275b1cd..4d9001c541 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShareLocationHelper.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShareLocationHelper.kt @@ -38,9 +38,9 @@ class ShareLocationHelper(private val app: TelegramApplication) { lastLocation = location if (location != null && app.isInternetConnectionAvailable) { - val shareLocationChats = app.settings.getShareLocationChats() - if (shareLocationChats.isNotEmpty()) { - app.telegramHelper.sendLiveLocationMessage(shareLocationChats, MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC, location.latitude, location.longitude) + val chatLivePeriods = app.settings.chatLivePeriods + if (chatLivePeriods.isNotEmpty()) { + app.telegramHelper.sendLiveLocationMessage(chatLivePeriods, location.latitude, location.longitude) } lastLocationMessageSentTime = System.currentTimeMillis() } diff --git a/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramHelper.kt b/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramHelper.kt index 8e55b4ab56..d055bae924 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramHelper.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramHelper.kt @@ -385,15 +385,15 @@ class TelegramHelper private constructor() { * @latitude Latitude of the location * @longitude Longitude of the location */ - fun sendLiveLocationMessage(chatIds: List, livePeriod: Int, latitude: Double, longitude: Double): Boolean { + fun sendLiveLocationMessage(chatLivePeriods: Map, latitude: Double, longitude: Double): Boolean { if (!requestingActiveLiveLocationMessages && haveAuthorization) { if (needRefreshActiveLiveLocationMessages) { getActiveLiveLocationMessages { - sendLiveLocationImpl(chatIds, livePeriod, latitude, longitude) + sendLiveLocationImpl(chatLivePeriods, latitude, longitude) } needRefreshActiveLiveLocationMessages = false } else { - sendLiveLocationImpl(chatIds, livePeriod, latitude, longitude) + sendLiveLocationImpl(chatLivePeriods, latitude, longitude) } return true } @@ -428,24 +428,24 @@ class TelegramHelper private constructor() { } } - private fun sendLiveLocationImpl(chatIds: List, livePeriod: Int, latitude: Double, longitude: Double) { - val lp = when { - livePeriod < MIN_LOCATION_MESSAGE_LIVE_PERIOD_SEC -> MIN_LOCATION_MESSAGE_LIVE_PERIOD_SEC - livePeriod > MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC -> MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC - else -> livePeriod - } + private fun sendLiveLocationImpl(chatLivePeriods: Map, latitude: Double, longitude: Double) { val location = TdApi.Location(latitude, longitude) - val content = TdApi.InputMessageLocation(location, lp) - - for (chatId in chatIds) { + chatLivePeriods.forEach { chatId, livePeriod -> + val content = TdApi.InputMessageLocation(location, livePeriod.toInt()) val msgId = chatLiveMessages[chatId] if (msgId != null) { if (msgId != 0L) { - client?.send(TdApi.EditMessageLiveLocation(chatId, msgId, null, location), liveLocationMessageUpdatesHandler) + client?.send( + TdApi.EditMessageLiveLocation(chatId, msgId, null, location), + liveLocationMessageUpdatesHandler + ) } } else { chatLiveMessages[chatId] = 0L - client?.send(TdApi.SendMessage(chatId, 0, false, true, null, content), liveLocationMessageUpdatesHandler) + client?.send( + TdApi.SendMessage(chatId, 0, false, true, null, content), + liveLocationMessageUpdatesHandler + ) } } } diff --git a/OsmAnd-telegram/src/net/osmand/telegram/ui/MainActivity.kt b/OsmAnd-telegram/src/net/osmand/telegram/ui/MainActivity.kt index 5b822397f3..7456d13608 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/ui/MainActivity.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/ui/MainActivity.kt @@ -159,7 +159,7 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene if (AndroidUtils.isLocationPermissionAvailable(this)) { app.locationProvider.resumeAllUpdates() } else { - requestLocationPermission() + AndroidUtils.requestLocationPermission(this) } if (settings.hasAnyChatToShowOnMap() && osmandAidlHelper.isOsmandNotInstalled()) { showOsmandMissingDialog() @@ -373,10 +373,6 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene } } - private fun requestLocationPermission() { - ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), PERMISSION_REQUEST_LOCATION) - } - override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) if (grantResults.isEmpty()) { @@ -475,7 +471,7 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene if (settings.hasAnyChatToShareLocation()) { if (!AndroidUtils.isLocationPermissionAvailable(view.context)) { if (isChecked) { - requestLocationPermission() + AndroidUtils.requestLocationPermission(this@MainActivity) } } else { app.shareLocationHelper.startSharingLocation() diff --git a/OsmAnd-telegram/src/net/osmand/telegram/ui/SetTimeDialogFragment.kt b/OsmAnd-telegram/src/net/osmand/telegram/ui/SetTimeDialogFragment.kt index c534b0c897..fff610c7d2 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/ui/SetTimeDialogFragment.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/ui/SetTimeDialogFragment.kt @@ -11,12 +11,12 @@ import android.view.View import android.view.ViewGroup import android.widget.ImageView import android.widget.TextView -import android.widget.Toast import net.osmand.telegram.R import net.osmand.telegram.TelegramApplication import net.osmand.telegram.helpers.ShareLocationHelper import net.osmand.telegram.helpers.TelegramUiHelper import net.osmand.telegram.ui.SetTimeDialogFragment.SetTimeListAdapter.ChatViewHolder +import net.osmand.telegram.utils.AndroidUtils import org.drinkless.td.libcore.telegram.TdApi import java.util.concurrent.TimeUnit @@ -26,13 +26,14 @@ class SetTimeDialogFragment : DialogFragment() { get() = activity?.application as TelegramApplication private val telegramHelper get() = app.telegramHelper + private val settings get() = app.settings private val adapter = SetTimeListAdapter() private lateinit var timeForAllTitle: TextView private lateinit var timeForAllValue: TextView - private val chatIdsToDuration = HashMap() + private val chatLivePeriods = HashMap() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -76,7 +77,15 @@ class SetTimeDialogFragment : DialogFragment() { view.findViewById(R.id.primary_btn).apply { text = getString(R.string.shared_string_share) setOnClickListener { - Toast.makeText(context, "Share", Toast.LENGTH_SHORT).show() + if (!AndroidUtils.isLocationPermissionAvailable(view.context)) { + AndroidUtils.requestLocationPermission(activity!!) + } else { + chatLivePeriods.forEach { chatId, livePeriod -> + settings.shareLocationToChat(chatId, true, livePeriod) + } + app.shareLocationHelper.startSharingLocation() + dismiss() + } } } @@ -91,25 +100,26 @@ class SetTimeDialogFragment : DialogFragment() { override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) val chats = mutableListOf() - for ((id, duration) in chatIdsToDuration) { + for ((id, livePeriod) in chatLivePeriods) { chats.add(id) - chats.add(duration) + chats.add(livePeriod) } outState.putLongArray(CHATS_KEY, chats.toLongArray()) } private fun readFromBundle(bundle: Bundle?) { - chatIdsToDuration.clear() + chatLivePeriods.clear() bundle?.getLongArray(CHATS_KEY)?.also { for (i in 0 until it.size step 2) { - chatIdsToDuration[it[i]] = it[i + 1] + val livePeriod = settings.getChatLivePeriod(it[i]) + chatLivePeriods[it[i]] = livePeriod ?: it[i + 1] } } } private fun getTimeForAll(useDefValue: Boolean = false): Long { val returnVal = if (useDefValue) DEFAULT_VISIBLE_TIME_SECONDS else NO_VALUE - val iterator = chatIdsToDuration.values.iterator() + val iterator = chatLivePeriods.values.iterator() if (!iterator.hasNext()) { return returnVal } @@ -127,7 +137,7 @@ class SetTimeDialogFragment : DialogFragment() { if (timeForAll != NO_VALUE) { timeForAllTitle.text = getString(R.string.visible_time_for_all) timeForAllValue.visibility = View.VISIBLE - timeForAllValue.text = formatDuration(timeForAll) + timeForAllValue.text = formatLivePeriod(timeForAll) } else { timeForAllTitle.text = getString(R.string.set_visible_time_for_all) timeForAllValue.visibility = View.GONE @@ -136,7 +146,7 @@ class SetTimeDialogFragment : DialogFragment() { private fun selectDuration(id: Long? = null) { val timeForAll = getTimeForAll(true) - val defSeconds = if (id == null) timeForAll else chatIdsToDuration[id] ?: timeForAll + val defSeconds = if (id == null) timeForAll else chatLivePeriods[id] ?: timeForAll val (defHours, defMinutes) = secondsToHoursAndMinutes(defSeconds) TimePickerDialog( context, @@ -145,10 +155,10 @@ class SetTimeDialogFragment : DialogFragment() { TimeUnit.MINUTES.toSeconds(minutes.toLong()) if (seconds >= ShareLocationHelper.MIN_LOCATION_MESSAGE_LIVE_PERIOD_SEC) { if (id != null) { - chatIdsToDuration[id] = seconds + chatLivePeriods[id] = seconds } else { - chatIdsToDuration.keys.forEach { - chatIdsToDuration[it] = seconds + chatLivePeriods.keys.forEach { + chatLivePeriods[it] = seconds } } updateTimeForAllRow() @@ -164,7 +174,7 @@ class SetTimeDialogFragment : DialogFragment() { return Pair(hours.toInt(), minutes.toInt()) } - private fun formatDuration(seconds: Long): String { + private fun formatLivePeriod(seconds: Long): String { val (hours, minutes) = secondsToHoursAndMinutes(seconds) return when { hours != 0 && minutes == 0 -> getString(R.string.hours_format, hours) @@ -175,7 +185,7 @@ class SetTimeDialogFragment : DialogFragment() { private fun updateList() { val chats: MutableList = mutableListOf() - telegramHelper.getChatList().filter { chatIdsToDuration.keys.contains(it.chatId) } + telegramHelper.getChatList().filter { chatLivePeriods.keys.contains(it.chatId) } .forEach { orderedChat -> telegramHelper.getChat(orderedChat.chatId)?.also { chats.add(it) } } @@ -204,7 +214,7 @@ class SetTimeDialogFragment : DialogFragment() { holder.description?.text = "Some description" // FIXME holder.textInArea?.apply { visibility = View.VISIBLE - chatIdsToDuration[chat.id]?.also { text = formatDuration(it) } + chatLivePeriods[chat.id]?.also { text = formatLivePeriod(it) } } holder.bottomShadow?.visibility = View.GONE holder.itemView.setOnClickListener { diff --git a/OsmAnd-telegram/src/net/osmand/telegram/utils/AndroidUtils.kt b/OsmAnd-telegram/src/net/osmand/telegram/utils/AndroidUtils.kt index 286548d7ff..9605612c51 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/utils/AndroidUtils.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/utils/AndroidUtils.kt @@ -19,6 +19,8 @@ import android.view.inputmethod.InputMethodManager import java.io.File object AndroidUtils { + + private const val PERMISSION_REQUEST_LOCATION = 1 private fun isHardwareKeyboardAvailable(context: Context): Boolean { return context.resources.configuration.keyboard != Configuration.KEYBOARD_NOKEYS @@ -50,6 +52,11 @@ object AndroidUtils { return ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED } + + fun requestLocationPermission(activity: Activity) { + ActivityCompat.requestPermissions(activity, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), PERMISSION_REQUEST_LOCATION) + } + fun dpToPx(ctx: Context, dp: Float): Int { val r = ctx.resources return TypedValue.applyDimension(