Add ability to share location to contacts
This commit is contained in:
parent
4c2cfb9c97
commit
9b6aa48639
6 changed files with 334 additions and 75 deletions
|
@ -44,8 +44,8 @@ private val LOC_HISTORY_VALUES_SEC = listOf(
|
|||
)
|
||||
|
||||
private const val SEND_MY_LOC_DEFAULT_INDEX = 6
|
||||
private const val STALE_LOC_DEFAULT_INDEX = 4
|
||||
private const val LOC_HISTORY_DEFAULT_INDEX = 2
|
||||
private const val STALE_LOC_DEFAULT_INDEX = 0
|
||||
private const val LOC_HISTORY_DEFAULT_INDEX = 7
|
||||
|
||||
private const val SETTINGS_NAME = "osmand_telegram_settings"
|
||||
|
||||
|
@ -113,6 +113,15 @@ class TelegramSettings(private val app: TelegramApplication) {
|
|||
|
||||
fun isSharingLocationToChat(chatId: Long) = shareChatsInfo.containsKey(chatId)
|
||||
|
||||
fun isSharingLocationToUser(userId: Int): Boolean {
|
||||
shareChatsInfo.forEach { (_, shareInfo: ShareChatInfo) ->
|
||||
if (shareInfo.userId == userId) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun hasAnyChatToShowOnMap() = !hiddenOnMapChats.containsAll(getLiveNowChats())
|
||||
|
||||
fun isShowingChatOnMap(chatId: Long) = !hiddenOnMapChats.contains(chatId)
|
||||
|
@ -132,35 +141,33 @@ class TelegramSettings(private val app: TelegramApplication) {
|
|||
addActiveTime: Long = ADDITIONAL_ACTIVE_TIME_VALUES_SEC[0]
|
||||
) {
|
||||
if (share) {
|
||||
val lp: Long = when {
|
||||
livePeriod < TelegramHelper.MIN_LOCATION_MESSAGE_LIVE_PERIOD_SEC -> TelegramHelper.MIN_LOCATION_MESSAGE_LIVE_PERIOD_SEC.toLong()
|
||||
else -> livePeriod
|
||||
}
|
||||
var shareChatInfo = shareChatsInfo[chatId]
|
||||
if (shareChatInfo == null) {
|
||||
shareChatInfo = ShareChatInfo()
|
||||
}
|
||||
val currentTime = System.currentTimeMillis() / 1000
|
||||
val user = app.telegramHelper.getCurrentUser()
|
||||
if (user != null && currentSharingMode != user.id.toString() && shareChatInfo.start == -1L) {
|
||||
shareChatInfo.shouldSendViaBotMessage = true
|
||||
val chat = app.telegramHelper.getChat(chatId)
|
||||
if (chat != null && (chat.type is TdApi.ChatTypePrivate || chat.type is TdApi.ChatTypeSecret)) {
|
||||
shareChatInfo.userId = app.telegramHelper.getUserIdFromChatType(chat.type)
|
||||
}
|
||||
|
||||
shareChatInfo.chatId = chatId
|
||||
shareChatInfo.start = currentTime
|
||||
if (shareChatInfo.livePeriod == -1L) {
|
||||
shareChatInfo.livePeriod = lp
|
||||
}
|
||||
shareChatInfo.userSetLivePeriod = lp
|
||||
shareChatInfo.userSetLivePeriodStart = currentTime
|
||||
shareChatInfo.currentMessageLimit = currentTime + Math.min(lp, TelegramHelper.MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC.toLong())
|
||||
shareChatInfo.additionalActiveTime = addActiveTime
|
||||
updateChatShareInfo(shareChatInfo, livePeriod, addActiveTime)
|
||||
shareChatsInfo[chatId] = shareChatInfo
|
||||
} else {
|
||||
shareChatsInfo.remove(chatId)
|
||||
}
|
||||
}
|
||||
|
||||
fun shareLocationToUser(
|
||||
userId: Int,
|
||||
livePeriod: Long = DEFAULT_VISIBLE_TIME_SECONDS,
|
||||
addActiveTime: Long = ADDITIONAL_ACTIVE_TIME_VALUES_SEC[0]
|
||||
) {
|
||||
val shareChatInfo = ShareChatInfo()
|
||||
shareChatInfo.userId = userId
|
||||
updateChatShareInfo(shareChatInfo, livePeriod, addActiveTime)
|
||||
app.telegramHelper.createPrivateChatWithUser(userId, shareChatInfo, shareChatsInfo)
|
||||
}
|
||||
|
||||
fun updateShareDevices(list: List<DeviceBot>) {
|
||||
shareDevices = list.toHashSet()
|
||||
}
|
||||
|
@ -235,10 +242,12 @@ class TelegramSettings(private val app: TelegramApplication) {
|
|||
fun updateShareInfo(message: TdApi.Message) {
|
||||
val shareChatInfo = shareChatsInfo[message.chatId]
|
||||
val content = message.content
|
||||
if (shareChatInfo != null && content is TdApi.MessageLocation) {
|
||||
if (shareChatInfo != null) {
|
||||
shareChatInfo.currentMessageId = message.id
|
||||
shareChatInfo.lastSuccessfulLocation = LatLon(content.location.latitude, content.location.longitude)
|
||||
shareChatInfo.lastSuccessfulSendTimeMs = Math.max(message.editDate, message.date) * 1000L
|
||||
if (content is TdApi.MessageLocation) {
|
||||
shareChatInfo.lastSuccessfulLocation = LatLon(content.location.latitude, content.location.longitude)
|
||||
shareChatInfo.lastSuccessfulSendTimeMs = Math.max(message.editDate, message.date) * 1000L
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -271,6 +280,31 @@ class TelegramSettings(private val app: TelegramApplication) {
|
|||
}
|
||||
}
|
||||
|
||||
private fun updateChatShareInfo(
|
||||
shareChatInfo: ShareChatInfo,
|
||||
livePeriod: Long = DEFAULT_VISIBLE_TIME_SECONDS,
|
||||
addActiveTime: Long = ADDITIONAL_ACTIVE_TIME_VALUES_SEC[0]
|
||||
) {
|
||||
val lp: Long = when {
|
||||
livePeriod < TelegramHelper.MIN_LOCATION_MESSAGE_LIVE_PERIOD_SEC -> TelegramHelper.MIN_LOCATION_MESSAGE_LIVE_PERIOD_SEC.toLong()
|
||||
else -> livePeriod
|
||||
}
|
||||
val currentTime = System.currentTimeMillis() / 1000
|
||||
val user = app.telegramHelper.getCurrentUser()
|
||||
if (user != null && currentSharingMode != user.id.toString() && shareChatInfo.start == -1L) {
|
||||
shareChatInfo.shouldSendViaBotMessage = true
|
||||
}
|
||||
|
||||
shareChatInfo.start = currentTime
|
||||
if (shareChatInfo.livePeriod == -1L) {
|
||||
shareChatInfo.livePeriod = lp
|
||||
}
|
||||
shareChatInfo.userSetLivePeriod = lp
|
||||
shareChatInfo.userSetLivePeriodStart = currentTime
|
||||
shareChatInfo.currentMessageLimit = currentTime + Math.min(lp, TelegramHelper.MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC.toLong())
|
||||
shareChatInfo.additionalActiveTime = addActiveTime
|
||||
}
|
||||
|
||||
private fun getNewSharingStatusHistoryItem(): SharingStatus {
|
||||
return SharingStatus().apply {
|
||||
statusChangeTime = System.currentTimeMillis()
|
||||
|
@ -472,6 +506,7 @@ class TelegramSettings(private val app: TelegramApplication) {
|
|||
shareChatsInfo.forEach { (chatId, chatInfo) ->
|
||||
val obj = JSONObject()
|
||||
obj.put(ShareChatInfo.CHAT_ID_KEY, chatId)
|
||||
obj.put(ShareChatInfo.USER_ID_KEY, chatInfo.userId)
|
||||
obj.put(ShareChatInfo.START_KEY, chatInfo.start)
|
||||
obj.put(ShareChatInfo.LIVE_PERIOD_KEY, chatInfo.livePeriod)
|
||||
obj.put(ShareChatInfo.LIMIT_KEY, chatInfo.currentMessageLimit)
|
||||
|
@ -493,6 +528,7 @@ class TelegramSettings(private val app: TelegramApplication) {
|
|||
val obj = json.getJSONObject(i)
|
||||
val shareInfo = ShareChatInfo().apply {
|
||||
chatId = obj.optLong(ShareChatInfo.CHAT_ID_KEY)
|
||||
userId = obj.optInt(ShareChatInfo.USER_ID_KEY)
|
||||
start = obj.optLong(ShareChatInfo.START_KEY)
|
||||
livePeriod = obj.optLong(ShareChatInfo.LIVE_PERIOD_KEY)
|
||||
currentMessageLimit = obj.optLong(ShareChatInfo.LIMIT_KEY)
|
||||
|
@ -738,6 +774,7 @@ class TelegramSettings(private val app: TelegramApplication) {
|
|||
class ShareChatInfo {
|
||||
|
||||
var chatId = -1L
|
||||
var userId = -1
|
||||
var start = -1L
|
||||
var livePeriod = -1L
|
||||
var currentMessageLimit = -1L
|
||||
|
@ -767,6 +804,7 @@ class TelegramSettings(private val app: TelegramApplication) {
|
|||
companion object {
|
||||
|
||||
internal const val CHAT_ID_KEY = "chatId"
|
||||
internal const val USER_ID_KEY = "userId"
|
||||
internal const val START_KEY = "start"
|
||||
internal const val LIVE_PERIOD_KEY = "livePeriod"
|
||||
internal const val LIMIT_KEY = "limit"
|
||||
|
|
|
@ -68,6 +68,7 @@ class TelegramHelper private constructor() {
|
|||
var lastTelegramUpdateTime: Int = 0
|
||||
|
||||
private val users = ConcurrentHashMap<Int, TdApi.User>()
|
||||
private val contacts = ConcurrentHashMap<Int, TdApi.User>()
|
||||
private val basicGroups = ConcurrentHashMap<Int, TdApi.BasicGroup>()
|
||||
private val supergroups = ConcurrentHashMap<Int, TdApi.Supergroup>()
|
||||
private val secretChats = ConcurrentHashMap<Int, TdApi.SecretChat>()
|
||||
|
@ -141,6 +142,8 @@ class TelegramHelper private constructor() {
|
|||
|
||||
fun getChatListIds() = getChatList().map { it.chatId }
|
||||
|
||||
fun getContacts() = contacts
|
||||
|
||||
fun getChatIds() = chats.keys().toList()
|
||||
|
||||
fun getChat(id: Long) = chats[id]
|
||||
|
@ -237,6 +240,7 @@ class TelegramHelper private constructor() {
|
|||
fun onTelegramChatsRead()
|
||||
fun onTelegramChatsChanged()
|
||||
fun onTelegramChatChanged(chat: TdApi.Chat)
|
||||
fun onTelegramChatCreated(chat: TdApi.Chat)
|
||||
fun onTelegramUserChanged(user: TdApi.User)
|
||||
fun onTelegramError(code: Int, message: String)
|
||||
}
|
||||
|
@ -561,6 +565,73 @@ class TelegramHelper private constructor() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun requestContacts(){
|
||||
client?.send(TdApi.GetContacts()) { obj ->
|
||||
when (obj.constructor) {
|
||||
TdApi.Error.CONSTRUCTOR -> {
|
||||
val error = obj as TdApi.Error
|
||||
if (error.code != IGNORED_ERROR_CODE) {
|
||||
listener?.onTelegramError(error.code, error.message)
|
||||
}
|
||||
}
|
||||
TdApi.Users.CONSTRUCTOR -> {
|
||||
val usersIds = obj as TdApi.Users
|
||||
usersIds.userIds.forEach {
|
||||
requestUser(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun requestUser(id: Int) {
|
||||
client?.send(TdApi.GetUser(id)) { obj ->
|
||||
when (obj.constructor) {
|
||||
TdApi.Error.CONSTRUCTOR -> {
|
||||
val error = obj as TdApi.Error
|
||||
if (error.code != IGNORED_ERROR_CODE) {
|
||||
listener?.onTelegramError(error.code, error.message)
|
||||
}
|
||||
}
|
||||
TdApi.User.CONSTRUCTOR -> {
|
||||
val user = obj as TdApi.User
|
||||
contacts[user.id] = user
|
||||
if (!hasLocalUserPhoto(user) && hasRemoteUserPhoto(user)) {
|
||||
requestUserPhoto(user)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun createPrivateChatWithUser(
|
||||
userId: Int,
|
||||
shareInfo: TelegramSettings.ShareChatInfo,
|
||||
shareChatsInfo: ConcurrentHashMap<Long, TelegramSettings.ShareChatInfo>
|
||||
) {
|
||||
client?.send(TdApi.CreatePrivateChat(userId, false)) { obj ->
|
||||
when (obj.constructor) {
|
||||
TdApi.Error.CONSTRUCTOR -> {
|
||||
val error = obj as TdApi.Error
|
||||
needRefreshActiveLiveLocationMessages = true
|
||||
if (error.code == MESSAGE_CANNOT_BE_EDITED_ERROR_CODE) {
|
||||
shareInfo.shouldDeletePreviousMessage = true
|
||||
} else if (error.code != IGNORED_ERROR_CODE) {
|
||||
shareInfo.hasSharingError = true
|
||||
outgoingMessagesListeners.forEach {
|
||||
it.onSendLiveLocationError(error.code, error.message)
|
||||
}
|
||||
}
|
||||
}
|
||||
TdApi.Chat.CONSTRUCTOR -> {
|
||||
shareInfo.chatId = (obj as TdApi.Chat).id
|
||||
shareChatsInfo[shareInfo.chatId] = shareInfo
|
||||
listener?.onTelegramChatCreated(obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun loadMessage(chatId: Long, messageId: Long) {
|
||||
requestMessage(chatId, messageId, this@TelegramHelper::addNewMessage)
|
||||
}
|
||||
|
@ -896,6 +967,7 @@ class TelegramHelper private constructor() {
|
|||
if (haveAuthorization) {
|
||||
requestChats(true)
|
||||
requestCurrentUser()
|
||||
requestContacts()
|
||||
}
|
||||
}
|
||||
val newAuthState = getTelegramAuthorizationState()
|
||||
|
@ -1085,6 +1157,9 @@ class TelegramHelper private constructor() {
|
|||
val updateUser = obj as TdApi.UpdateUser
|
||||
val user = updateUser.user
|
||||
users[updateUser.user.id] = user
|
||||
if (user.outgoingLink is TdApi.LinkStateIsContact) {
|
||||
contacts[user.id] = user
|
||||
}
|
||||
if (isOsmAndBot(user.id)) {
|
||||
osmandBot = user
|
||||
}
|
||||
|
|
|
@ -171,6 +171,10 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
|
|||
updateList()
|
||||
}
|
||||
|
||||
override fun onTelegramChatCreated(chat: TdApi.Chat) {
|
||||
updateList()
|
||||
}
|
||||
|
||||
override fun onTelegramUserChanged(user: TdApi.User) {
|
||||
updateList()
|
||||
}
|
||||
|
|
|
@ -254,6 +254,12 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene
|
|||
}
|
||||
}
|
||||
|
||||
override fun onTelegramChatCreated(chat: TdApi.Chat) {
|
||||
runOnUi {
|
||||
listeners.forEach { it.get()?.onTelegramChatCreated(chat) }
|
||||
}
|
||||
}
|
||||
|
||||
override fun onTelegramUserChanged(user: TdApi.User) {
|
||||
val photoPath = telegramHelper.getUserPhotoPath(user)
|
||||
if (photoPath != null) {
|
||||
|
|
|
@ -28,6 +28,7 @@ import net.osmand.telegram.utils.OsmandFormatter
|
|||
import org.drinkless.td.libcore.telegram.TdApi
|
||||
|
||||
private const val SELECTED_CHATS_KEY = "selected_chats"
|
||||
private const val SELECTED_CHATS_USERS = "selected_users"
|
||||
private const val SHARE_LOCATION_CHAT = 1
|
||||
private const val DEFAULT_CHAT = 0
|
||||
|
||||
|
@ -71,6 +72,7 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
private lateinit var appBarOutlineProvider: ViewOutlineProvider
|
||||
|
||||
private val selectedChats = HashSet<Long>()
|
||||
private val selectedUsers = HashSet<Long>()
|
||||
|
||||
private var actionButtonsListener: ActionButtonsListener? = null
|
||||
|
||||
|
@ -97,9 +99,8 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
|
||||
savedInstanceState?.apply {
|
||||
selectedChats.addAll(getLongArray(SELECTED_CHATS_KEY).toSet())
|
||||
if (selectedChats.isNotEmpty()) {
|
||||
actionButtonsListener?.switchButtonsVisibility(true)
|
||||
}
|
||||
selectedUsers.addAll(getLongArray(SELECTED_CHATS_USERS).toSet())
|
||||
actionButtonsListener?.switchButtonsVisibility((selectedUsers.isNotEmpty() || selectedChats.isNotEmpty()))
|
||||
}
|
||||
|
||||
val mainView = inflater.inflate(R.layout.fragment_my_location_tab, container, false)
|
||||
|
@ -191,7 +192,7 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
|
||||
mainView.findViewById<View>(R.id.stop_all_sharing_row).setOnClickListener {
|
||||
fragmentManager?.also { fm ->
|
||||
DisableSharingBottomSheet.showInstance(fm, this, adapter.chats.size)
|
||||
DisableSharingBottomSheet.showInstance(fm, this, adapter.items.size)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -274,7 +275,7 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
TelegramHelper.TelegramAuthorizationState.LOGGING_OUT,
|
||||
TelegramHelper.TelegramAuthorizationState.CLOSED,
|
||||
TelegramHelper.TelegramAuthorizationState.UNKNOWN -> {
|
||||
adapter.chats = mutableListOf()
|
||||
adapter.items = mutableListOf()
|
||||
}
|
||||
else -> Unit
|
||||
}
|
||||
|
@ -292,6 +293,11 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
updateContent()
|
||||
}
|
||||
|
||||
override fun onTelegramChatCreated(chat: TdApi.Chat) {
|
||||
sharingMode = settings.hasAnyChatToShareLocation()
|
||||
updateContent()
|
||||
}
|
||||
|
||||
override fun onTelegramUserChanged(user: TdApi.User) {
|
||||
if (user.id == telegramHelper.getCurrentUser()?.id) {
|
||||
updateCurrentUserPhoto()
|
||||
|
@ -303,9 +309,9 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
}
|
||||
|
||||
fun onPrimaryBtnClick() {
|
||||
if (selectedChats.isNotEmpty()) {
|
||||
if (selectedChats.isNotEmpty() || selectedUsers.isNotEmpty()) {
|
||||
val fm = fragmentManager ?: return
|
||||
SetTimeDialogFragment.showInstance(fm, selectedChats, this)
|
||||
SetTimeDialogFragment.showInstance(fm, selectedChats, selectedUsers, this)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -351,6 +357,7 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
|
||||
private fun clearSelection() {
|
||||
selectedChats.clear()
|
||||
selectedUsers.clear()
|
||||
adapter.notifyDataSetChanged()
|
||||
actionButtonsListener?.switchButtonsVisibility(false)
|
||||
}
|
||||
|
@ -453,8 +460,9 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
}
|
||||
|
||||
private fun updateList() {
|
||||
val chats: MutableList<TdApi.Chat> = mutableListOf()
|
||||
val items: MutableList<TdApi.Object> = mutableListOf()
|
||||
val currentUser = telegramHelper.getCurrentUser()
|
||||
val contacts = telegramHelper.getContacts()
|
||||
val chatList = if (sharingMode) {
|
||||
settings.getShareLocationChats()
|
||||
} else {
|
||||
|
@ -470,30 +478,56 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
continue
|
||||
}
|
||||
}
|
||||
chats.add(chat)
|
||||
items.add(chat)
|
||||
}
|
||||
}
|
||||
if (!sharingMode) {
|
||||
for (user in contacts.values) {
|
||||
if ((!sharingMode && settings.isSharingLocationToUser(user.id)) || user.id == currentUser?.id) {
|
||||
continue
|
||||
}
|
||||
items.add(user)
|
||||
}
|
||||
}
|
||||
if (sharingMode && settings.hasAnyChatToShareLocation()) {
|
||||
adapter.chats = sortAdapterItems(chats)
|
||||
adapter.items = sortAdapterItems(items)
|
||||
} else {
|
||||
adapter.chats = chats
|
||||
adapter.items = items
|
||||
}
|
||||
}
|
||||
|
||||
private fun sortAdapterItems(list: MutableList<TdApi.Chat>): MutableList<TdApi.Chat> {
|
||||
list.sortWith(Comparator<TdApi.Chat> { o1, o2 -> o1.title.compareTo(o2.title) })
|
||||
private fun sortAdapterItems(list: MutableList<TdApi.Object>): MutableList<TdApi.Object> {
|
||||
list.sortWith(Comparator<TdApi.Object> { o1, o2 ->
|
||||
val title1 = when (o1) {
|
||||
is TdApi.Chat -> o1.title
|
||||
is TdApi.User -> TelegramUiHelper.getUserName(o1)
|
||||
else -> ""
|
||||
}
|
||||
val title2 = when (o2) {
|
||||
is TdApi.Chat -> o2.title
|
||||
is TdApi.User -> TelegramUiHelper.getUserName(o2)
|
||||
else -> ""
|
||||
}
|
||||
title1.compareTo(title2)
|
||||
})
|
||||
return list
|
||||
}
|
||||
|
||||
inner class MyLocationListAdapter : RecyclerView.Adapter<MyLocationListAdapter.BaseViewHolder>() {
|
||||
var chats = mutableListOf<TdApi.Chat>()
|
||||
var items = mutableListOf<TdApi.Object>()
|
||||
set(value) {
|
||||
field = value
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun getItemViewType(position: Int): Int {
|
||||
return if (settings.isSharingLocationToChat(chats[position].id) && sharingMode) {
|
||||
val item = items[position]
|
||||
val id = when (item) {
|
||||
is TdApi.Chat -> item.id
|
||||
is TdApi.User -> item.id.toLong()
|
||||
else -> -1
|
||||
}
|
||||
return if (settings.isSharingLocationToChat(id) && sharingMode) {
|
||||
SHARE_LOCATION_CHAT
|
||||
} else {
|
||||
DEFAULT_CHAT
|
||||
|
@ -518,14 +552,34 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
|
||||
val chat = chats[position]
|
||||
val lastItem = position == itemCount - 1
|
||||
val placeholderId = if (telegramHelper.isGroup(chat)) R.drawable.img_group_picture else R.drawable.img_user_picture
|
||||
val live = settings.isSharingLocationToChat(chat.id)
|
||||
val shareInfo = settings.getChatsShareInfo()[chat.id]
|
||||
val item = items[position]
|
||||
val isChat = item is TdApi.Chat
|
||||
val itemId = if (isChat) {
|
||||
(item as TdApi.Chat).id
|
||||
} else {
|
||||
(item as TdApi.User).id.toLong()
|
||||
}
|
||||
|
||||
TelegramUiHelper.setupPhoto(app, holder.icon, chat.photo?.small?.local?.path, placeholderId, false)
|
||||
holder.title?.text = chat.title
|
||||
val lastItem = position == itemCount - 1
|
||||
val placeholderId = if (isChat && telegramHelper.isGroup(item as TdApi.Chat)) R.drawable.img_group_picture else R.drawable.img_user_picture
|
||||
val live = (isChat && settings.isSharingLocationToChat(itemId))
|
||||
val shareInfo = if (isChat) settings.getChatsShareInfo()[itemId] else null
|
||||
|
||||
val photoPath = when (item) {
|
||||
is TdApi.Chat -> item.photo?.small?.local?.path
|
||||
is TdApi.User -> item.profilePhoto?.small?.local?.path
|
||||
else -> null
|
||||
}
|
||||
|
||||
TelegramUiHelper.setupPhoto(app, holder.icon, photoPath, placeholderId, false)
|
||||
|
||||
val title = when (item) {
|
||||
is TdApi.Chat -> item.title
|
||||
is TdApi.User -> TelegramUiHelper.getUserName(item)
|
||||
else -> null
|
||||
}
|
||||
|
||||
holder.title?.text = title
|
||||
|
||||
if (holder is ChatViewHolder) {
|
||||
holder.description?.visibility = View.GONE
|
||||
|
@ -535,21 +589,33 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
holder.checkBox?.apply {
|
||||
visibility = View.VISIBLE
|
||||
setOnCheckedChangeListener(null)
|
||||
isChecked = selectedChats.contains(chat.id)
|
||||
isChecked = if (isChat) {
|
||||
selectedChats.contains(itemId)
|
||||
} else {
|
||||
selectedUsers.contains(itemId)
|
||||
}
|
||||
setOnCheckedChangeListener { _, isChecked ->
|
||||
if (isChecked) {
|
||||
selectedChats.add(chat.id)
|
||||
if (isChat) {
|
||||
selectedChats.add(itemId)
|
||||
} else {
|
||||
selectedUsers.add(itemId)
|
||||
}
|
||||
} else {
|
||||
selectedChats.remove(chat.id)
|
||||
if (isChat) {
|
||||
selectedChats.remove(itemId)
|
||||
} else {
|
||||
selectedUsers.remove(itemId)
|
||||
}
|
||||
}
|
||||
actionButtonsListener?.switchButtonsVisibility(selectedChats.isNotEmpty())
|
||||
actionButtonsListener?.switchButtonsVisibility(selectedChats.isNotEmpty() || selectedUsers.isNotEmpty())
|
||||
}
|
||||
}
|
||||
}
|
||||
holder.bottomShadow?.visibility = if (lastItem) View.VISIBLE else View.GONE
|
||||
holder.itemView.setOnClickListener {
|
||||
if (live) {
|
||||
settings.shareLocationToChat(chat.id, false)
|
||||
settings.shareLocationToChat(itemId, false)
|
||||
shareLocationHelper.stopSharingLocation()
|
||||
notifyItemChanged(position)
|
||||
} else {
|
||||
|
@ -563,11 +629,11 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
isChecked = live
|
||||
setOnCheckedChangeListener { _, isChecked ->
|
||||
if (!isChecked) {
|
||||
settings.shareLocationToChat(chat.id, false)
|
||||
settings.shareLocationToChat(itemId, false)
|
||||
if (shareInfo != null) {
|
||||
telegramHelper.stopSendingLiveLocationToChat(shareInfo)
|
||||
}
|
||||
removeItem(chat)
|
||||
removeItem(item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -591,7 +657,11 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
val expireTime = shareInfo?.getChatLiveMessageExpireTime() ?: 0
|
||||
val newLivePeriod = expireTime + (shareInfo?.additionalActiveTime ?: ADDITIONAL_ACTIVE_TIME_VALUES_SEC[0])
|
||||
val nextAdditionalActiveTime = shareInfo?.getNextAdditionalActiveTime() ?: ADDITIONAL_ACTIVE_TIME_VALUES_SEC[1]
|
||||
settings.shareLocationToChat(chat.id, true, newLivePeriod, nextAdditionalActiveTime)
|
||||
if (isChat) {
|
||||
settings.shareLocationToChat(itemId, true, newLivePeriod, nextAdditionalActiveTime)
|
||||
} else {
|
||||
settings.shareLocationToUser(itemId.toInt(), newLivePeriod, nextAdditionalActiveTime)
|
||||
}
|
||||
notifyItemChanged(position)
|
||||
}
|
||||
}
|
||||
|
@ -616,9 +686,9 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
|
||||
private fun getStopSharingVisibility(expiresIn: Long) = if (expiresIn > 0) View.VISIBLE else View.INVISIBLE
|
||||
|
||||
private fun removeItem(chat: TdApi.Chat) {
|
||||
chats.remove(chat)
|
||||
if (chats.isEmpty()) {
|
||||
private fun removeItem(chat: TdApi.Object) {
|
||||
items.remove(chat)
|
||||
if (items.isEmpty()) {
|
||||
sharingMode = false
|
||||
updateContent()
|
||||
shareLocationHelper.stopSharingLocation()
|
||||
|
@ -627,7 +697,7 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
}
|
||||
}
|
||||
|
||||
override fun getItemCount() = chats.size
|
||||
override fun getItemCount() = items.size
|
||||
|
||||
abstract inner class BaseViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
val icon: ImageView? = view.findViewById(R.id.icon)
|
||||
|
|
|
@ -14,8 +14,8 @@ import android.widget.TextView
|
|||
import net.osmand.Location
|
||||
import net.osmand.data.LatLon
|
||||
import net.osmand.telegram.R
|
||||
import net.osmand.telegram.TelegramLocationProvider.TelegramLocationListener
|
||||
import net.osmand.telegram.TelegramLocationProvider.TelegramCompassListener
|
||||
import net.osmand.telegram.TelegramLocationProvider.TelegramLocationListener
|
||||
import net.osmand.telegram.helpers.ShareLocationHelper
|
||||
import net.osmand.telegram.helpers.TelegramUiHelper
|
||||
import net.osmand.telegram.ui.SetTimeDialogFragment.SetTimeListAdapter.ChatViewHolder
|
||||
|
@ -36,6 +36,7 @@ class SetTimeDialogFragment : BaseDialogFragment(), TelegramLocationListener, Te
|
|||
private lateinit var timeForAllValue: TextView
|
||||
|
||||
private val chatLivePeriods = HashMap<Long, Long>()
|
||||
private val userLivePeriods = HashMap<Long, Long>()
|
||||
|
||||
private var location: Location? = null
|
||||
private var heading: Float? = null
|
||||
|
@ -90,6 +91,9 @@ class SetTimeDialogFragment : BaseDialogFragment(), TelegramLocationListener, Te
|
|||
chatLivePeriods.forEach { (chatId, livePeriod) ->
|
||||
settings.shareLocationToChat(chatId, true, livePeriod)
|
||||
}
|
||||
userLivePeriods.forEach { (userId, livePeriod) ->
|
||||
settings.shareLocationToUser(userId.toInt(), livePeriod)
|
||||
}
|
||||
app.shareLocationHelper.startSharingLocation()
|
||||
targetFragment?.also {
|
||||
it.onActivityResult(targetRequestCode, LOCATION_SHARED_REQUEST_CODE, null)
|
||||
|
@ -121,7 +125,13 @@ class SetTimeDialogFragment : BaseDialogFragment(), TelegramLocationListener, Te
|
|||
chats.add(id)
|
||||
chats.add(livePeriod)
|
||||
}
|
||||
val users = mutableListOf<Long>()
|
||||
for ((id, livePeriod) in userLivePeriods) {
|
||||
users.add(id)
|
||||
users.add(livePeriod)
|
||||
}
|
||||
outState.putLongArray(CHATS_KEY, chats.toLongArray())
|
||||
outState.putLongArray(USERS_KEY, users.toLongArray())
|
||||
}
|
||||
|
||||
override fun updateLocation(location: Location?) {
|
||||
|
@ -167,17 +177,27 @@ class SetTimeDialogFragment : BaseDialogFragment(), TelegramLocationListener, Te
|
|||
|
||||
private fun readFromBundle(bundle: Bundle?) {
|
||||
chatLivePeriods.clear()
|
||||
userLivePeriods.clear()
|
||||
bundle?.getLongArray(CHATS_KEY)?.also {
|
||||
for (i in 0 until it.size step 2) {
|
||||
val livePeriod = settings.getChatLivePeriod(it[i])
|
||||
chatLivePeriods[it[i]] = livePeriod ?: it[i + 1]
|
||||
}
|
||||
}
|
||||
bundle?.getLongArray(USERS_KEY)?.also {
|
||||
for (j in 0 until it.size step 2) {
|
||||
val livePeriod = settings.getChatLivePeriod(it[j])
|
||||
userLivePeriods[it[j]] = livePeriod ?: it[j + 1]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getTimeForAll(useDefValue: Boolean = false): Long {
|
||||
val returnVal = if (useDefValue) DEFAULT_VISIBLE_TIME_SECONDS else NO_VALUE
|
||||
val iterator = chatLivePeriods.values.iterator()
|
||||
val allTime = mutableListOf<Long>()
|
||||
allTime.addAll(chatLivePeriods.values)
|
||||
allTime.addAll(userLivePeriods.values)
|
||||
val iterator = allTime.iterator()
|
||||
if (!iterator.hasNext()) {
|
||||
return returnVal
|
||||
}
|
||||
|
@ -202,7 +222,7 @@ class SetTimeDialogFragment : BaseDialogFragment(), TelegramLocationListener, Te
|
|||
}
|
||||
}
|
||||
|
||||
private fun selectDuration(id: Long? = null) {
|
||||
private fun selectDuration(id: Long? = null, isChat: Boolean = true) {
|
||||
val timeForAll = getTimeForAll(true)
|
||||
val defSeconds = if (id == null) timeForAll else chatLivePeriods[id] ?: timeForAll
|
||||
val (defHours, defMinutes) = secondsToHoursAndMinutes(defSeconds)
|
||||
|
@ -213,11 +233,18 @@ class SetTimeDialogFragment : BaseDialogFragment(), TelegramLocationListener, Te
|
|||
TimeUnit.MINUTES.toSeconds(minutes.toLong())
|
||||
if (seconds >= ShareLocationHelper.MIN_LOCATION_MESSAGE_LIVE_PERIOD_SEC) {
|
||||
if (id != null) {
|
||||
chatLivePeriods[id] = seconds
|
||||
if (isChat) {
|
||||
chatLivePeriods[id] = seconds
|
||||
} else {
|
||||
userLivePeriods[id] = seconds
|
||||
}
|
||||
} else {
|
||||
chatLivePeriods.keys.forEach {
|
||||
chatLivePeriods[it] = seconds
|
||||
}
|
||||
userLivePeriods.keys.forEach {
|
||||
userLivePeriods[it] = seconds
|
||||
}
|
||||
}
|
||||
updateTimeForAllRow()
|
||||
adapter.notifyDataSetChanged()
|
||||
|
@ -242,17 +269,19 @@ class SetTimeDialogFragment : BaseDialogFragment(), TelegramLocationListener, Te
|
|||
}
|
||||
|
||||
private fun updateList() {
|
||||
val chats: MutableList<TdApi.Chat> = mutableListOf()
|
||||
val items: MutableList<TdApi.Object> = mutableListOf()
|
||||
telegramHelper.getChatList().filter { chatLivePeriods.keys.contains(it.chatId) }
|
||||
.forEach { orderedChat ->
|
||||
telegramHelper.getChat(orderedChat.chatId)?.also { chats.add(it) }
|
||||
telegramHelper.getChat(orderedChat.chatId)?.also { items.add(it) }
|
||||
}
|
||||
adapter.chats = chats
|
||||
telegramHelper.getContacts().values.filter { userLivePeriods.keys.contains(it.id.toLong()) }
|
||||
.forEach { user -> items.add(user) }
|
||||
adapter.items = items
|
||||
}
|
||||
|
||||
inner class SetTimeListAdapter : RecyclerView.Adapter<ChatViewHolder>() {
|
||||
|
||||
var chats: List<TdApi.Chat> = emptyList()
|
||||
var items: List<TdApi.Object> = emptyList()
|
||||
set(value) {
|
||||
field = value
|
||||
notifyDataSetChanged()
|
||||
|
@ -265,18 +294,38 @@ class SetTimeDialogFragment : BaseDialogFragment(), TelegramLocationListener, Te
|
|||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ChatViewHolder, position: Int) {
|
||||
val chat = chats[position]
|
||||
val placeholderId = if (telegramHelper.isGroup(chat)) R.drawable.img_group_picture else R.drawable.img_user_picture
|
||||
val item = items[position]
|
||||
val isChat = item is TdApi.Chat
|
||||
val itemId = if (isChat) {
|
||||
(item as TdApi.Chat).id
|
||||
} else {
|
||||
(item as TdApi.User).id.toLong()
|
||||
}
|
||||
|
||||
TelegramUiHelper.setupPhoto(app, holder.icon, chat.photo?.small?.local?.path, placeholderId, false)
|
||||
holder.title?.text = chat.title
|
||||
val placeholderId = if (isChat && telegramHelper.isGroup((item as TdApi.Chat))) R.drawable.img_group_picture else R.drawable.img_user_picture
|
||||
|
||||
if (telegramHelper.isGroup(chat)) {
|
||||
val photoPath = when (item) {
|
||||
is TdApi.Chat -> item.photo?.small?.local?.path
|
||||
is TdApi.User -> item.profilePhoto?.small?.local?.path
|
||||
else -> null
|
||||
}
|
||||
|
||||
TelegramUiHelper.setupPhoto(app, holder.icon, photoPath, placeholderId, false)
|
||||
|
||||
val title = when (item) {
|
||||
is TdApi.Chat -> item.title
|
||||
is TdApi.User -> TelegramUiHelper.getUserName(item)
|
||||
else -> null
|
||||
}
|
||||
|
||||
holder.title?.text = title
|
||||
|
||||
if (isChat && telegramHelper.isGroup((item as TdApi.Chat))) {
|
||||
holder.locationViewContainer?.visibility = View.GONE
|
||||
holder.description?.visibility = View.VISIBLE
|
||||
holder.description?.text = getString(R.string.shared_string_group)
|
||||
} else {
|
||||
val message = telegramHelper.getChatMessages(chat.id).firstOrNull()
|
||||
val message = telegramHelper.getChatMessages(itemId).firstOrNull()
|
||||
val content = message?.content
|
||||
if (message != null && content is TdApi.MessageLocation && (location != null && content.location != null)) {
|
||||
val lastUpdated = telegramHelper.getLastUpdatedTime(message)
|
||||
|
@ -301,15 +350,19 @@ class SetTimeDialogFragment : BaseDialogFragment(), TelegramLocationListener, Te
|
|||
|
||||
holder.textInArea?.apply {
|
||||
visibility = View.VISIBLE
|
||||
chatLivePeriods[chat.id]?.also { text = formatLivePeriod(it) }
|
||||
if (isChat) {
|
||||
chatLivePeriods[itemId]?.also { text = formatLivePeriod(it) }
|
||||
} else {
|
||||
userLivePeriods[itemId]?.also { text = formatLivePeriod(it) }
|
||||
}
|
||||
}
|
||||
holder.bottomShadow?.visibility = View.GONE
|
||||
holder.itemView.setOnClickListener {
|
||||
selectDuration(chat.id)
|
||||
selectDuration(itemId, isChat)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount() = chats.size
|
||||
override fun getItemCount() = items.size
|
||||
|
||||
inner class ChatViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
|
||||
val icon: ImageView? = view.findViewById(R.id.icon)
|
||||
|
@ -329,18 +382,31 @@ class SetTimeDialogFragment : BaseDialogFragment(), TelegramLocationListener, Te
|
|||
|
||||
private const val TAG = "SetTimeDialogFragment"
|
||||
private const val CHATS_KEY = "chats_key"
|
||||
private const val USERS_KEY = "users_key"
|
||||
private const val DEFAULT_VISIBLE_TIME_SECONDS = 60 * 60L // 1 hour
|
||||
private const val NO_VALUE = -1L
|
||||
|
||||
fun showInstance(fm: FragmentManager, chatIds: Set<Long>, target: Fragment): Boolean {
|
||||
fun showInstance(fm: FragmentManager, chatIds: Set<Long>, usersIds: Set<Long>, target: Fragment): Boolean {
|
||||
return try {
|
||||
val chats = mutableListOf<Long>()
|
||||
for (id in chatIds) {
|
||||
chats.add(id)
|
||||
chats.add(DEFAULT_VISIBLE_TIME_SECONDS)
|
||||
}
|
||||
val users = mutableListOf<Long>()
|
||||
for (id in usersIds) {
|
||||
users.add(id)
|
||||
users.add(DEFAULT_VISIBLE_TIME_SECONDS)
|
||||
}
|
||||
SetTimeDialogFragment().apply {
|
||||
arguments = Bundle().apply { putLongArray(CHATS_KEY, chats.toLongArray()) }
|
||||
arguments = Bundle().apply {
|
||||
if (chats.isNotEmpty()) {
|
||||
putLongArray(CHATS_KEY, chats.toLongArray())
|
||||
}
|
||||
if (users.isNotEmpty()) {
|
||||
putLongArray(USERS_KEY, users.toLongArray())
|
||||
}
|
||||
}
|
||||
setTargetFragment(target, LOCATION_SHARED_REQUEST_CODE)
|
||||
show(fm, TAG)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue