suggestion list on first screen
This commit is contained in:
parent
0e4a5f3cd4
commit
c5cfb47950
4 changed files with 149 additions and 10 deletions
59
OsmAnd-telegram/res/layout/last_share_list_item.xml
Normal file
59
OsmAnd-telegram/res/layout/last_share_list_item.xml
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/card_bg_color">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/container"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/selectableItemBackground"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:minHeight="@dimen/list_item_height"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/icon"
|
||||||
|
android:layout_width="@dimen/list_item_icon_size_big"
|
||||||
|
android:layout_height="@dimen/list_item_icon_size_big"
|
||||||
|
android:layout_marginStart="@dimen/list_item_icon_margin_left"
|
||||||
|
android:layout_marginLeft="@dimen/list_item_icon_margin_left"
|
||||||
|
android:layout_marginEnd="@dimen/list_item_icon_margin_right"
|
||||||
|
android:layout_marginRight="@dimen/list_item_icon_margin_right"
|
||||||
|
tools:src="@drawable/img_user_picture" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<net.osmand.telegram.ui.views.TextViewEx
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:textColor="?android:textColorPrimary"
|
||||||
|
android:textSize="@dimen/list_item_title_text_size"
|
||||||
|
app:typeface="@string/font_roboto_regular"
|
||||||
|
tools:text="Share to Share Location" />
|
||||||
|
|
||||||
|
<net.osmand.telegram.ui.views.TextViewEx
|
||||||
|
android:id="@+id/time"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:textColor="?attr/android:textColorSecondary"
|
||||||
|
android:textSize="@dimen/list_item_description_text_size"
|
||||||
|
app:typeface="@string/font_roboto_regular"
|
||||||
|
tools:text="for 1 hour" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
|
@ -115,7 +115,7 @@ class TelegramSettings(private val app: TelegramApplication) {
|
||||||
private var hiddenOnMapChats: Set<Long> = emptySet()
|
private var hiddenOnMapChats: Set<Long> = emptySet()
|
||||||
private var shareDevices: Set<DeviceBot> = emptySet()
|
private var shareDevices: Set<DeviceBot> = emptySet()
|
||||||
private var liveTracksInfo = emptyList<LiveTrackInfo>()
|
private var liveTracksInfo = emptyList<LiveTrackInfo>()
|
||||||
private var lastChatsInfo = ConcurrentHashMap<Long, LastChatInfo>()
|
var lastChatsInfo = ConcurrentHashMap<Long, LastChatInfo>()
|
||||||
|
|
||||||
var sharingStatusChanges = ConcurrentLinkedQueue<SharingStatus>()
|
var sharingStatusChanges = ConcurrentLinkedQueue<SharingStatus>()
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,8 @@ import android.support.v4.app.DialogFragment
|
||||||
import android.support.v4.app.Fragment
|
import android.support.v4.app.Fragment
|
||||||
import android.support.v4.app.FragmentManager
|
import android.support.v4.app.FragmentManager
|
||||||
import android.support.v4.app.FragmentPagerAdapter
|
import android.support.v4.app.FragmentPagerAdapter
|
||||||
|
import android.support.v4.view.PagerAdapter
|
||||||
|
import android.support.v4.view.ViewPager
|
||||||
import android.support.v7.app.AlertDialog
|
import android.support.v7.app.AlertDialog
|
||||||
import android.support.v7.app.AppCompatActivity
|
import android.support.v7.app.AppCompatActivity
|
||||||
import android.support.v7.widget.ListPopupWindow
|
import android.support.v7.widget.ListPopupWindow
|
||||||
|
@ -22,7 +24,6 @@ import net.osmand.PlatformUtil
|
||||||
import net.osmand.telegram.R
|
import net.osmand.telegram.R
|
||||||
import net.osmand.telegram.TelegramApplication
|
import net.osmand.telegram.TelegramApplication
|
||||||
import net.osmand.telegram.helpers.OsmandAidlHelper
|
import net.osmand.telegram.helpers.OsmandAidlHelper
|
||||||
import net.osmand.telegram.helpers.TelegramHelper
|
|
||||||
import net.osmand.telegram.helpers.TelegramHelper.*
|
import net.osmand.telegram.helpers.TelegramHelper.*
|
||||||
import net.osmand.telegram.ui.LoginDialogFragment.LoginDialogType
|
import net.osmand.telegram.ui.LoginDialogFragment.LoginDialogType
|
||||||
import net.osmand.telegram.ui.MyLocationTabFragment.ActionButtonsListener
|
import net.osmand.telegram.ui.MyLocationTabFragment.ActionButtonsListener
|
||||||
|
@ -43,7 +44,7 @@ private const val MY_LOCATION_TAB_POS = 0
|
||||||
private const val LIVE_NOW_TAB_POS = 1
|
private const val LIVE_NOW_TAB_POS = 1
|
||||||
private const val TIMELINE_TAB_POS = 2
|
private const val TIMELINE_TAB_POS = 2
|
||||||
|
|
||||||
class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListener, TelegramIncomingMessagesListener {
|
class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListener, TelegramIncomingMessagesListener, DataSetListener {
|
||||||
|
|
||||||
private val log = PlatformUtil.getLog(MainActivity::class.java)
|
private val log = PlatformUtil.getLog(MainActivity::class.java)
|
||||||
|
|
||||||
|
@ -66,6 +67,7 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene
|
||||||
private lateinit var buttonsBar: LinearLayout
|
private lateinit var buttonsBar: LinearLayout
|
||||||
private lateinit var bottomNav: BottomNavigationView
|
private lateinit var bottomNav: BottomNavigationView
|
||||||
private lateinit var coordinatorLayout: CoordinatorLayout
|
private lateinit var coordinatorLayout: CoordinatorLayout
|
||||||
|
private lateinit var viewPager: ViewPager
|
||||||
|
|
||||||
private var snackbarShown = false
|
private var snackbarShown = false
|
||||||
|
|
||||||
|
@ -81,7 +83,7 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene
|
||||||
|
|
||||||
paused = false
|
paused = false
|
||||||
|
|
||||||
val viewPager = findViewById<LockableViewPager>(R.id.view_pager).apply {
|
viewPager = findViewById<LockableViewPager>(R.id.view_pager).apply {
|
||||||
swipeLocked = true
|
swipeLocked = true
|
||||||
offscreenPageLimit = 3
|
offscreenPageLimit = 3
|
||||||
adapter = ViewPagerAdapter(supportFragmentManager)
|
adapter = ViewPagerAdapter(supportFragmentManager)
|
||||||
|
@ -484,6 +486,10 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onDataSetChanged() {
|
||||||
|
viewPager.adapter?.notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
|
||||||
private fun showOsmandMissingDialog() {
|
private fun showOsmandMissingDialog() {
|
||||||
OsmandMissingDialogFragment().show(supportFragmentManager, null)
|
OsmandMissingDialogFragment().show(supportFragmentManager, null)
|
||||||
}
|
}
|
||||||
|
@ -510,5 +516,13 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene
|
||||||
override fun getItem(position: Int) = fragments[position]
|
override fun getItem(position: Int) = fragments[position]
|
||||||
|
|
||||||
override fun getCount() = fragments.size
|
override fun getCount() = fragments.size
|
||||||
|
|
||||||
|
override fun getItemPosition(`object`: Any): Int {
|
||||||
|
return PagerAdapter.POSITION_NONE
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface DataSetListener {
|
||||||
|
fun onDataSetChanged()
|
||||||
|
}
|
||||||
|
|
|
@ -20,10 +20,8 @@ import android.text.style.StyleSpan
|
||||||
import android.view.*
|
import android.view.*
|
||||||
import android.view.animation.LinearInterpolator
|
import android.view.animation.LinearInterpolator
|
||||||
import android.widget.*
|
import android.widget.*
|
||||||
import net.osmand.telegram.ADDITIONAL_ACTIVE_TIME_VALUES_SEC
|
import net.osmand.PlatformUtil
|
||||||
import net.osmand.telegram.R
|
import net.osmand.telegram.*
|
||||||
import net.osmand.telegram.SHARE_TYPE_MAP
|
|
||||||
import net.osmand.telegram.TelegramApplication
|
|
||||||
import net.osmand.telegram.helpers.LocationMessages
|
import net.osmand.telegram.helpers.LocationMessages
|
||||||
import net.osmand.telegram.helpers.TelegramHelper
|
import net.osmand.telegram.helpers.TelegramHelper
|
||||||
import net.osmand.telegram.helpers.TelegramHelper.TelegramListener
|
import net.osmand.telegram.helpers.TelegramHelper.TelegramListener
|
||||||
|
@ -31,9 +29,11 @@ import net.osmand.telegram.helpers.TelegramUiHelper
|
||||||
import net.osmand.telegram.utils.AndroidUtils
|
import net.osmand.telegram.utils.AndroidUtils
|
||||||
import net.osmand.telegram.utils.OsmandFormatter
|
import net.osmand.telegram.utils.OsmandFormatter
|
||||||
import org.drinkless.td.libcore.telegram.TdApi
|
import org.drinkless.td.libcore.telegram.TdApi
|
||||||
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
|
||||||
private const val SELECTED_CHATS_KEY = "selected_chats"
|
private const val SELECTED_CHATS_KEY = "selected_chats"
|
||||||
private const val SELECTED_CHATS_USERS = "selected_users"
|
private const val SELECTED_CHATS_USERS = "selected_users"
|
||||||
|
private const val LAST_SHARE_CHAT = 2
|
||||||
private const val SHARE_LOCATION_CHAT = 1
|
private const val SHARE_LOCATION_CHAT = 1
|
||||||
private const val DEFAULT_CHAT = 0
|
private const val DEFAULT_CHAT = 0
|
||||||
|
|
||||||
|
@ -41,6 +41,8 @@ private const val ADAPTER_UPDATE_INTERVAL_MIL = 5 * 1000L // 5 sec
|
||||||
|
|
||||||
class MyLocationTabFragment : Fragment(), TelegramListener {
|
class MyLocationTabFragment : Fragment(), TelegramListener {
|
||||||
|
|
||||||
|
private val log = PlatformUtil.getLog(MyLocationTabFragment::class.java)
|
||||||
|
|
||||||
private var textMarginSmall: Int = 0
|
private var textMarginSmall: Int = 0
|
||||||
private var textMarginBig: Int = 0
|
private var textMarginBig: Int = 0
|
||||||
private var searchBoxHeight: Int = 0
|
private var searchBoxHeight: Int = 0
|
||||||
|
@ -85,6 +87,8 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
||||||
|
|
||||||
private var updateEnable: Boolean = false
|
private var updateEnable: Boolean = false
|
||||||
|
|
||||||
|
private lateinit var lastChatsInfo: ConcurrentHashMap<Long, TelegramSettings.LastChatInfo>
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
|
@ -234,6 +238,8 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lastChatsInfo = settings.lastChatsInfo
|
||||||
|
|
||||||
return mainView
|
return mainView
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -517,10 +523,25 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
||||||
if (sharingMode && settings.hasAnyChatToShareLocation()) {
|
if (sharingMode && settings.hasAnyChatToShareLocation()) {
|
||||||
adapter.items = sortAdapterItems(items)
|
adapter.items = sortAdapterItems(items)
|
||||||
} else {
|
} else {
|
||||||
|
items.addAll(0, getLastShareItems(items))
|
||||||
adapter.items = items
|
adapter.items = items
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getLastShareItems(items: MutableList<TdApi.Object>): MutableList<TdApi.Object> {
|
||||||
|
val lastItems: MutableList<TdApi.Object> = mutableListOf()
|
||||||
|
items.forEach {
|
||||||
|
val id = when (it) {
|
||||||
|
is TdApi.Chat -> it.id
|
||||||
|
else -> -1
|
||||||
|
}
|
||||||
|
if (lastChatsInfo.containsKey(id)) {
|
||||||
|
lastItems.add(LastChat(it as TdApi.Chat, lastChatsInfo[id]!!.livePeriod))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lastItems
|
||||||
|
}
|
||||||
|
|
||||||
private fun sortAdapterItems(list: MutableList<TdApi.Object>): MutableList<TdApi.Object> {
|
private fun sortAdapterItems(list: MutableList<TdApi.Object>): MutableList<TdApi.Object> {
|
||||||
list.sortWith(Comparator<TdApi.Object> { o1, o2 ->
|
list.sortWith(Comparator<TdApi.Object> { o1, o2 ->
|
||||||
val title1 = when (o1) {
|
val title1 = when (o1) {
|
||||||
|
@ -553,7 +574,9 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
||||||
is TdApi.User -> item.id.toLong()
|
is TdApi.User -> item.id.toLong()
|
||||||
else -> -1
|
else -> -1
|
||||||
}
|
}
|
||||||
return if (settings.isSharingLocationToChat(id) && sharingMode) {
|
return if (item is LastChat) {
|
||||||
|
LAST_SHARE_CHAT
|
||||||
|
} else if (settings.isSharingLocationToChat(id) && sharingMode) {
|
||||||
SHARE_LOCATION_CHAT
|
SHARE_LOCATION_CHAT
|
||||||
} else {
|
} else {
|
||||||
DEFAULT_CHAT
|
DEFAULT_CHAT
|
||||||
|
@ -572,6 +595,11 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
||||||
.inflate(R.layout.user_list_item, parent, false)
|
.inflate(R.layout.user_list_item, parent, false)
|
||||||
ChatViewHolder(view)
|
ChatViewHolder(view)
|
||||||
}
|
}
|
||||||
|
LAST_SHARE_CHAT -> {
|
||||||
|
val view = LayoutInflater.from(parent.context)
|
||||||
|
.inflate(R.layout.last_share_list_item, parent, false)
|
||||||
|
LastChatViewHolder(view)
|
||||||
|
}
|
||||||
else -> throw RuntimeException("Unsupported view type: $viewType")
|
else -> throw RuntimeException("Unsupported view type: $viewType")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -593,6 +621,7 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
||||||
val shareInfo = if (isChat) settings.getChatsShareInfo()[itemId] else null
|
val shareInfo = if (isChat) settings.getChatsShareInfo()[itemId] else null
|
||||||
|
|
||||||
val photoPath = when (item) {
|
val photoPath = when (item) {
|
||||||
|
is LastChat -> item.chat.photo?.small?.local?.path
|
||||||
is TdApi.Chat -> item.photo?.small?.local?.path
|
is TdApi.Chat -> item.photo?.small?.local?.path
|
||||||
is TdApi.User -> item.profilePhoto?.small?.local?.path
|
is TdApi.User -> item.profilePhoto?.small?.local?.path
|
||||||
else -> null
|
else -> null
|
||||||
|
@ -602,6 +631,13 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
||||||
|
|
||||||
val currentUserId = telegramHelper.getCurrentUserId()
|
val currentUserId = telegramHelper.getCurrentUserId()
|
||||||
val title = when (item) {
|
val title = when (item) {
|
||||||
|
is LastChat -> {
|
||||||
|
if (telegramHelper.isPrivateChat(item.chat) && (item.chat.type as TdApi.ChatTypePrivate).userId == currentUserId) {
|
||||||
|
getString(R.string.saved_messages)
|
||||||
|
} else {
|
||||||
|
item.chat.title
|
||||||
|
}
|
||||||
|
}
|
||||||
is TdApi.Chat -> {
|
is TdApi.Chat -> {
|
||||||
if (telegramHelper.isPrivateChat(item) && (item.type as TdApi.ChatTypePrivate).userId == currentUserId) {
|
if (telegramHelper.isPrivateChat(item) && (item.type as TdApi.ChatTypePrivate).userId == currentUserId) {
|
||||||
getString(R.string.saved_messages)
|
getString(R.string.saved_messages)
|
||||||
|
@ -669,6 +705,11 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
||||||
settings.shareLocationToChat(itemId, false)
|
settings.shareLocationToChat(itemId, false)
|
||||||
if (shareInfo != null) {
|
if (shareInfo != null) {
|
||||||
telegramHelper.stopSendingLiveLocationToChat(shareInfo)
|
telegramHelper.stopSendingLiveLocationToChat(shareInfo)
|
||||||
|
app.settings.lastChatsInfo[shareInfo.chatId] = TelegramSettings.LastChatInfo().apply {
|
||||||
|
chatId = shareInfo.chatId
|
||||||
|
livePeriod = shareInfo.livePeriod
|
||||||
|
}
|
||||||
|
log.info("Save chat to last: ${shareInfo.chatId}")
|
||||||
}
|
}
|
||||||
removeItem(item)
|
removeItem(item)
|
||||||
}
|
}
|
||||||
|
@ -743,6 +784,24 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
||||||
text = description
|
text = description
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (holder is LastChatViewHolder) {
|
||||||
|
val sharingTime = SpannableStringBuilder("${getString(R.string.sharing_time)}: ")
|
||||||
|
val formattedTime = OsmandFormatter.getFormattedDuration(app, (item as LastChat).time, false)
|
||||||
|
val start = sharingTime.length
|
||||||
|
sharingTime.append(formattedTime)
|
||||||
|
sharingTime.setSpan(StyleSpan(Typeface.BOLD), start, sharingTime.length, 0)
|
||||||
|
sharingTime.setSpan(ForegroundColorSpan(ContextCompat.getColor(app, R.color.ctrl_active_light)), start, sharingTime.length, 0)
|
||||||
|
holder.time?.text = sharingTime
|
||||||
|
|
||||||
|
holder.container?.setOnClickListener {
|
||||||
|
if (!AndroidUtils.isLocationPermissionAvailable(view!!.context)) {
|
||||||
|
AndroidUtils.requestLocationPermission(activity!!)
|
||||||
|
} else {
|
||||||
|
settings.shareLocationToChat((item as LastChat).chat.id, true, item.time)
|
||||||
|
app.shareLocationHelper.startSharingLocation()
|
||||||
|
(activity as DataSetListener).onDataSetChanged()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -778,9 +837,16 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
||||||
val sharingExpiresLine: TextView? = view.findViewById(R.id.expires_line)
|
val sharingExpiresLine: TextView? = view.findViewById(R.id.expires_line)
|
||||||
val gpsPointsLine: TextView? = view.findViewById(R.id.gps_points_line)
|
val gpsPointsLine: TextView? = view.findViewById(R.id.gps_points_line)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inner class LastChatViewHolder(val view: View) : BaseViewHolder(view) {
|
||||||
|
val container: LinearLayout? = view.findViewById(R.id.container)
|
||||||
|
val time: TextView? = view.findViewById(R.id.time)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ActionButtonsListener {
|
interface ActionButtonsListener {
|
||||||
fun switchButtonsVisibility(visible: Boolean)
|
fun switchButtonsVisibility(visible: Boolean)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class LastChat internal constructor(val chat: TdApi.Chat, val time: Long) : TdApi.Chat()
|
Loading…
Reference in a new issue