Merge pull request #5881 from osmandapp/TravelUiImprovements
SetTimeDialog UI Improvements
This commit is contained in:
commit
7d3ea473e8
7 changed files with 128 additions and 31 deletions
|
@ -1,4 +1,7 @@
|
|||
<resources>
|
||||
<string name="time_ago">ago</string>
|
||||
<string name="last_response">Last response</string>
|
||||
<string name="shared_string_group">Group</string>
|
||||
<string name="logout_no_internet_msg">To properly log out from your Telegram account, the Internet is needed.</string>
|
||||
<string name="shared_string_close">Close</string>
|
||||
<string name="disconnect_from_telegram_desc">To invoke access to your Telegram account from OsmAnd, open Telegram, go to Settings - Privacy and Security - Sessions and terminate OsmAnd Telegram session. After that, OsmAnd Location Sharing will no longer have access to your account, and you will not be able to use this app until you log in again.</string>
|
||||
|
|
|
@ -54,7 +54,7 @@ class ShowLocationHelper(private val app: TelegramApplication) {
|
|||
val messages = telegramHelper.getMessages()
|
||||
for (message in messages) {
|
||||
val date = Math.max(message.date, message.editDate) * 1000L
|
||||
val expired = System.currentTimeMillis() - date > app.settings.locHistoryTime
|
||||
val expired = System.currentTimeMillis() - date > app.settings.locHistoryTime * 1000L
|
||||
if (expired) {
|
||||
removeMapPoint(message.chatId, message)
|
||||
}
|
||||
|
|
|
@ -177,6 +177,8 @@ class TelegramHelper private constructor() {
|
|||
return chat.type is TdApi.ChatTypeSupergroup || chat.type is TdApi.ChatTypeBasicGroup
|
||||
}
|
||||
|
||||
fun getLastUpdatedTime(message: TdApi.Message) = Math.max(message.editDate, message.date)
|
||||
|
||||
fun isPrivateChat(chat: TdApi.Chat): Boolean = chat.type is TdApi.ChatTypePrivate
|
||||
|
||||
private fun isChannel(chat: TdApi.Chat): Boolean {
|
||||
|
@ -485,9 +487,7 @@ class TelegramHelper private constructor() {
|
|||
val viaBot = isOsmAndBot(message.viaBotUserId)
|
||||
val oldContent = message.content
|
||||
if (oldContent is TdApi.MessageText) {
|
||||
message.content = parseOsmAndBotLocation(oldContent.text.text).apply {
|
||||
created = message.date
|
||||
}
|
||||
message.content = parseOsmAndBotLocation(oldContent.text.text)
|
||||
} else if (oldContent is TdApi.MessageLocation && (fromBot || viaBot)) {
|
||||
message.content = parseOsmAndBotLocation(message)
|
||||
}
|
||||
|
@ -761,13 +761,7 @@ class TelegramHelper private constructor() {
|
|||
name = getOsmAndBotDeviceName(message)
|
||||
lat = messageLocation.location.latitude
|
||||
lon = messageLocation.location.longitude
|
||||
created = message.date
|
||||
val date = message.editDate
|
||||
lastUpdated = if (date != 0) {
|
||||
date
|
||||
} else {
|
||||
message.date
|
||||
}
|
||||
lastUpdated = getLastUpdatedTime(message)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -777,7 +771,6 @@ class TelegramHelper private constructor() {
|
|||
name = oldContent.name
|
||||
lat = messageLocation.location.latitude
|
||||
lon = messageLocation.location.longitude
|
||||
created = oldContent.created
|
||||
lastUpdated = (System.currentTimeMillis() / 1000).toInt()
|
||||
}
|
||||
}
|
||||
|
@ -1069,9 +1062,7 @@ class TelegramHelper private constructor() {
|
|||
synchronized(message) {
|
||||
val newContent = updateMessageContent.newContent
|
||||
message.content = if (newContent is TdApi.MessageText) {
|
||||
val messageOsmAndBotLocation = parseOsmAndBotLocation(newContent.text.text)
|
||||
messageOsmAndBotLocation.created = message.date
|
||||
messageOsmAndBotLocation
|
||||
parseOsmAndBotLocation(newContent.text.text)
|
||||
} else if (newContent is TdApi.MessageLocation &&
|
||||
(isOsmAndBot(message.senderUserId) || isOsmAndBot(message.viaBotUserId))) {
|
||||
parseOsmAndBotLocationContent(message.content as MessageOsmAndBotLocation, newContent)
|
||||
|
|
|
@ -54,8 +54,7 @@ object TelegramUiHelper {
|
|||
val type = chat.type
|
||||
val message = messages.firstOrNull()
|
||||
if (message != null) {
|
||||
res.lastUpdated = message.editDate
|
||||
res.created = message.date
|
||||
res.lastUpdated = helper.getLastUpdatedTime(message)
|
||||
}
|
||||
if (type is TdApi.ChatTypePrivate || type is TdApi.ChatTypeSecret) {
|
||||
val userId = getUserIdFromChatType(type)
|
||||
|
@ -125,7 +124,6 @@ object TelegramUiHelper {
|
|||
latLon = LatLon(content.lat, content.lon)
|
||||
placeholderId = R.drawable.img_user_picture
|
||||
lastUpdated = content.lastUpdated
|
||||
created = content.created
|
||||
}
|
||||
} else {
|
||||
null
|
||||
|
@ -147,8 +145,7 @@ object TelegramUiHelper {
|
|||
photoPath = helper.getUserPhotoPath(user)
|
||||
placeholderId = R.drawable.img_user_picture
|
||||
userId = message.senderUserId
|
||||
lastUpdated = message.editDate
|
||||
created = message.date
|
||||
lastUpdated = helper.getLastUpdatedTime(message)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -168,8 +165,6 @@ object TelegramUiHelper {
|
|||
internal set
|
||||
var lastUpdated: Int = 0
|
||||
internal set
|
||||
var created: Int = 0
|
||||
internal set
|
||||
|
||||
abstract fun canBeOpenedOnMap(): Boolean
|
||||
|
||||
|
|
|
@ -361,12 +361,12 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
|
|||
}
|
||||
}
|
||||
|
||||
private fun getListItemLiveTimeDescr(item: ListItem):String {
|
||||
return getString(R.string.shared_string_live) +
|
||||
": ${OsmandFormatter.getFormattedDuration(app, getListItemLiveTime(item))}"
|
||||
private fun getListItemLiveTimeDescr(item: ListItem): String {
|
||||
val formattedTime = OsmandFormatter.getFormattedDuration(app, getListItemLiveTime(item))
|
||||
return getString(R.string.last_response) + ": $formattedTime " + getString(R.string.time_ago)
|
||||
}
|
||||
|
||||
private fun getListItemLiveTime(item: ListItem): Long = (System.currentTimeMillis() / 1000) - item.created
|
||||
private fun getListItemLiveTime(item: ListItem): Long = (System.currentTimeMillis() / 1000) - item.lastUpdated
|
||||
|
||||
private fun showPopupMenu(holder: ChatViewHolder, chatId: Long) {
|
||||
val ctx = holder.itemView.context
|
||||
|
|
|
@ -577,23 +577,25 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
}
|
||||
|
||||
holder.stopSharingDescr?.apply {
|
||||
visibility = View.VISIBLE
|
||||
visibility = getStopSharingVisibility(expiresIn)
|
||||
text = "${getText(R.string.stop_at)}:"
|
||||
}
|
||||
|
||||
holder.stopSharingFirstPart?.apply {
|
||||
visibility = View.VISIBLE
|
||||
visibility = getStopSharingVisibility(expiresIn)
|
||||
text = OsmandFormatter.getFormattedTime(expiresIn)
|
||||
}
|
||||
|
||||
holder.stopSharingSecondPart?.apply {
|
||||
visibility = View.VISIBLE
|
||||
visibility = getStopSharingVisibility(expiresIn)
|
||||
text = "(${getString(R.string.in_time,
|
||||
OsmandFormatter.getFormattedDuration(context!!, expiresIn, true))})"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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()) {
|
||||
|
|
|
@ -12,16 +12,23 @@ import android.view.View
|
|||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import net.osmand.Location
|
||||
import net.osmand.data.LatLon
|
||||
import net.osmand.telegram.R
|
||||
import net.osmand.telegram.TelegramApplication
|
||||
import net.osmand.telegram.TelegramLocationProvider.TelegramLocationListener
|
||||
import net.osmand.telegram.TelegramLocationProvider.TelegramCompassListener
|
||||
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 net.osmand.telegram.utils.OsmandFormatter
|
||||
import net.osmand.telegram.utils.UiUtils
|
||||
import net.osmand.util.MapUtils
|
||||
import org.drinkless.td.libcore.telegram.TdApi
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class SetTimeDialogFragment : DialogFragment() {
|
||||
class SetTimeDialogFragment : DialogFragment(), TelegramLocationListener, TelegramCompassListener {
|
||||
|
||||
private val app: TelegramApplication
|
||||
get() = activity?.application as TelegramApplication
|
||||
|
@ -29,6 +36,7 @@ class SetTimeDialogFragment : DialogFragment() {
|
|||
private val telegramHelper get() = app.telegramHelper
|
||||
private val settings get() = app.settings
|
||||
|
||||
private lateinit var locationViewCache: UiUtils.UpdateLocationViewCache
|
||||
private val adapter = SetTimeListAdapter()
|
||||
|
||||
private lateinit var timeForAllTitle: TextView
|
||||
|
@ -36,6 +44,10 @@ class SetTimeDialogFragment : DialogFragment() {
|
|||
|
||||
private val chatLivePeriods = HashMap<Long, Long>()
|
||||
|
||||
private var location: Location? = null
|
||||
private var heading: Float? = null
|
||||
private var locationUiUpdateAllowed: Boolean = true
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setStyle(DialogFragment.STYLE_NO_FRAME, R.style.AppTheme_NoActionbar)
|
||||
|
@ -66,6 +78,12 @@ class SetTimeDialogFragment : DialogFragment() {
|
|||
view.findViewById<RecyclerView>(R.id.recycler_view).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
adapter = this@SetTimeDialogFragment.adapter
|
||||
addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
||||
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
|
||||
super.onScrollStateChanged(recyclerView, newState)
|
||||
locationUiUpdateAllowed = newState == RecyclerView.SCROLL_STATE_IDLE
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
view.findViewById<TextView>(R.id.secondary_btn).apply {
|
||||
|
@ -98,9 +116,16 @@ class SetTimeDialogFragment : DialogFragment() {
|
|||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
locationViewCache = app.uiUtils.getUpdateLocationViewCache()
|
||||
startLocationUpdate()
|
||||
updateList()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
stopLocationUpdate()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
val chats = mutableListOf<Long>()
|
||||
|
@ -111,6 +136,47 @@ class SetTimeDialogFragment : DialogFragment() {
|
|||
outState.putLongArray(CHATS_KEY, chats.toLongArray())
|
||||
}
|
||||
|
||||
override fun updateLocation(location: Location?) {
|
||||
val loc = this.location
|
||||
val newLocation = loc == null && location != null
|
||||
val locationChanged = loc != null && location != null
|
||||
&& loc.latitude != location.latitude
|
||||
&& loc.longitude != location.longitude
|
||||
if (newLocation || locationChanged) {
|
||||
this.location = location
|
||||
updateLocationUi()
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateCompassValue(value: Float) {
|
||||
// 99 in next line used to one-time initialize arrows (with reference vs. fixed-north direction)
|
||||
// on non-compass devices
|
||||
val lastHeading = heading ?: 99f
|
||||
heading = value
|
||||
if (Math.abs(MapUtils.degreesDiff(lastHeading.toDouble(), value.toDouble())) > 5) {
|
||||
updateLocationUi()
|
||||
} else {
|
||||
heading = lastHeading
|
||||
}
|
||||
}
|
||||
|
||||
private fun startLocationUpdate() {
|
||||
app.locationProvider.addLocationListener(this)
|
||||
app.locationProvider.addCompassListener(this)
|
||||
updateLocationUi()
|
||||
}
|
||||
|
||||
private fun stopLocationUpdate() {
|
||||
app.locationProvider.removeLocationListener(this)
|
||||
app.locationProvider.removeCompassListener(this)
|
||||
}
|
||||
|
||||
private fun updateLocationUi() {
|
||||
if (locationUiUpdateAllowed) {
|
||||
app.runInUIThread { adapter.notifyDataSetChanged() }
|
||||
}
|
||||
}
|
||||
|
||||
private fun readFromBundle(bundle: Bundle?) {
|
||||
chatLivePeriods.clear()
|
||||
bundle?.getLongArray(CHATS_KEY)?.also {
|
||||
|
@ -216,7 +282,35 @@ class SetTimeDialogFragment : DialogFragment() {
|
|||
|
||||
TelegramUiHelper.setupPhoto(app, holder.icon, chat.photo?.small?.local?.path, placeholderId, false)
|
||||
holder.title?.text = chat.title
|
||||
holder.description?.visibility = View.INVISIBLE
|
||||
|
||||
if (telegramHelper.isGroup(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 content = message?.content
|
||||
if (message != null && content is TdApi.MessageLocation && (location != null && content.location != null)) {
|
||||
val lastUpdated = telegramHelper.getLastUpdatedTime(message)
|
||||
holder.description?.visibility = View.VISIBLE
|
||||
holder.description?.text = getListItemLiveTimeDescr(lastUpdated)
|
||||
|
||||
holder.locationViewContainer?.visibility = View.VISIBLE
|
||||
locationViewCache.outdatedLocation = System.currentTimeMillis() / 1000 -
|
||||
lastUpdated > settings.staleLocTime
|
||||
|
||||
app.uiUtils.updateLocationView(
|
||||
holder.directionIcon,
|
||||
holder.distanceText,
|
||||
LatLon(content.location.latitude, content.location.longitude),
|
||||
locationViewCache
|
||||
)
|
||||
} else {
|
||||
holder.locationViewContainer?.visibility = View.GONE
|
||||
holder.description?.visibility = View.INVISIBLE
|
||||
}
|
||||
}
|
||||
|
||||
holder.textInArea?.apply {
|
||||
visibility = View.VISIBLE
|
||||
chatLivePeriods[chat.id]?.also { text = formatLivePeriod(it) }
|
||||
|
@ -229,9 +323,21 @@ class SetTimeDialogFragment : DialogFragment() {
|
|||
|
||||
override fun getItemCount() = chats.size
|
||||
|
||||
private fun getListItemLiveTimeDescr(lastUpdated: Int): String {
|
||||
val formattedTime = OsmandFormatter.getFormattedDuration(app, getListItemLiveTime(lastUpdated))
|
||||
return "$formattedTime " + getString(R.string.time_ago)
|
||||
}
|
||||
|
||||
private fun getListItemLiveTime(lastUpdated: Int): Long {
|
||||
return (System.currentTimeMillis() / 1000) - lastUpdated
|
||||
}
|
||||
|
||||
inner class ChatViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
|
||||
val icon: ImageView? = view.findViewById(R.id.icon)
|
||||
val title: TextView? = view.findViewById(R.id.title)
|
||||
val directionIcon: ImageView? = view.findViewById(R.id.direction_icon)
|
||||
val distanceText: TextView? = view.findViewById(R.id.distance_text)
|
||||
val locationViewContainer: View? = view.findViewById(R.id.location_view_container)
|
||||
val description: TextView? = view.findViewById(R.id.description)
|
||||
val textInArea: TextView? = view.findViewById(R.id.text_in_area)
|
||||
val bottomShadow: View? = view.findViewById(R.id.bottom_shadow)
|
||||
|
|
Loading…
Reference in a new issue