Merge pull request #5667 from osmandapp/AddChatIdsToDuration
Add chat ids to duration in settings
This commit is contained in:
commit
af7c9bed4b
6 changed files with 72 additions and 40 deletions
|
@ -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<Long, Long>()
|
||||
|
||||
private var shareLocationChats: Set<Long> = emptySet()
|
||||
private var showOnMapChats: Set<Long> = 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) {
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -385,15 +385,15 @@ class TelegramHelper private constructor() {
|
|||
* @latitude Latitude of the location
|
||||
* @longitude Longitude of the location
|
||||
*/
|
||||
fun sendLiveLocationMessage(chatIds: List<Long>, livePeriod: Int, latitude: Double, longitude: Double): Boolean {
|
||||
fun sendLiveLocationMessage(chatLivePeriods: Map<Long, Long>, 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<Long>, 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<Long, Long>, 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
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<String>, 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()
|
||||
|
|
|
@ -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<Long, Long>()
|
||||
private val chatLivePeriods = HashMap<Long, Long>()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
@ -76,7 +77,15 @@ class SetTimeDialogFragment : DialogFragment() {
|
|||
view.findViewById<TextView>(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<Long>()
|
||||
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<TdApi.Chat> = 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 {
|
||||
|
|
|
@ -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(
|
||||
|
|
Loading…
Reference in a new issue