Merge pull request #5667 from osmandapp/AddChatIdsToDuration

Add chat ids to duration in settings
This commit is contained in:
Alexander Sytnyk 2018-07-13 17:13:21 +03:00 committed by GitHub
commit af7c9bed4b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 72 additions and 40 deletions

View file

@ -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) {

View file

@ -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()
}

View file

@ -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
)
}
}
}

View file

@ -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()

View file

@ -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 {

View file

@ -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(