Merge pull request #5978 from osmandapp/LiveNowSorting

Live now sorting
This commit is contained in:
Alexander Sytnyk 2018-09-05 11:39:14 +03:00 committed by GitHub
commit 561814cf90
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 507 additions and 36 deletions

View file

@ -0,0 +1,65 @@
<?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:orientation="vertical"
tools:layout_gravity="bottom">
<android.support.design.widget.CoordinatorLayout
android:id="@+id/scroll_view_container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v4.widget.NestedScrollView
android:id="@+id/scroll_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:behavior_hideable="true"
app:behavior_peekHeight="@dimen/bottom_sheet_peek_height"
app:layout_behavior="@string/bottom_sheet_behavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/card_bg_color"
android:orientation="vertical">
<net.osmand.telegram.ui.views.TextViewEx
android:layout_width="match_parent"
android:layout_height="@dimen/list_item_height_min"
android:paddingLeft="@dimen/content_padding_standard"
android:paddingRight="@dimen/content_padding_standard"
android:text="@string/shared_string_sort_by"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/list_item_title_text_size"
app:firstBaselineToTopHeight="28sp"
app:typeface="@string/font_roboto_medium" />
<LinearLayout
android:id="@+id/items_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/card_bg_color">
<include
layout="@layout/secondary_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/content_padding_half" />
</FrameLayout>
</LinearLayout>

View file

@ -59,6 +59,58 @@
android:textColor="?android:attr/textColorSecondary"
android:textSize="@dimen/descr_text_size" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/app_bar_divider" />
<LinearLayout
android:id="@+id/sort_by_container"
android:layout_width="match_parent"
android:layout_height="@dimen/list_header_height"
android:background="@color/screen_bg_light"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/selectableItemBackground"
android:orientation="horizontal"
android:paddingLeft="@dimen/content_padding_standard"
android:paddingRight="@dimen/content_padding_standard">
<net.osmand.telegram.ui.views.TextViewEx
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical|start"
android:layout_weight="0.5"
android:ellipsize="end"
android:gravity="center_vertical"
android:maxLines="1"
android:text="@string/shared_string_sort"
android:textColor="@color/ctrl_active_light"
android:textSize="@dimen/descr_text_size"
app:typeface="@string/font_roboto_medium" />
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/sort_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical|end"
android:layout_weight="0.5"
android:drawablePadding="@dimen/content_padding_standard"
android:ellipsize="end"
android:gravity="center|end"
android:maxLines="1"
android:textColor="@color/ctrl_active_light"
android:textSize="@dimen/descr_text_size"
app:typeface="@string/font_roboto_medium"
tools:text="@string/by_group" />
</LinearLayout>
</LinearLayout>
</android.support.design.widget.AppBarLayout>
<FrameLayout

View file

@ -7,7 +7,9 @@
android:layout_height="wrap_content"
android:orientation="vertical">
<include layout="@layout/list_item_divider"/>
<include
android:id="@+id/top_divider"
layout="@layout/list_item_divider"/>
<LinearLayout
android:layout_width="match_parent"
@ -18,7 +20,7 @@
<LinearLayout
android:id="@+id/user_row"
android:layout_width="match_parent"
android:layout_height="@dimen/list_item_height"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:gravity="center_vertical">
@ -48,12 +50,45 @@
android:maxLines="1"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/list_item_title_text_size"
app:firstBaselineToTopHeight="@dimen/list_item_baseline_to_top_height_big"
app:typeface="@string/font_roboto_regular"
tools:text="Share location"/>
<LinearLayout
android:id="@+id/group_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:visibility="gone"
tools:visibility="visible">
<ImageView
android:id="@+id/group_icon"
android:layout_width="@dimen/list_item_icon_size_small"
android:layout_height="@dimen/list_item_icon_size_small"
android:layout_gravity="bottom"
android:layout_marginEnd="@dimen/content_padding_small"
android:layout_marginRight="@dimen/content_padding_small"
tools:src="@drawable/img_group_picture" />
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/group_title"
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:firstBaselineToTopHeight="@dimen/list_item_baseline_to_top_height"
app:typeface="@string/font_roboto_regular"
tools:text="@string/shared_string_group" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:paddingBottom="@dimen/content_padding_half">
<LinearLayout
android:id="@+id/location_view_container"
@ -67,8 +102,9 @@
android:id="@+id/direction_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="4dp"
android:layout_marginRight="4dp"
android:layout_gravity="bottom"
android:layout_marginEnd="@dimen/content_padding_small"
android:layout_marginRight="@dimen/content_padding_small"
tools:src="@drawable/ic_direction_arrow"
tools:tint="@color/ctrl_active_light"/>
@ -78,11 +114,12 @@
android:layout_height="wrap_content"
android:maxLines="1"
android:textSize="@dimen/list_item_description_text_size"
app:firstBaselineToTopHeight="@dimen/list_item_baseline_to_top_height_small"
app:typeface="@string/font_roboto_medium"
tools:text="213 m"
tools:textColor="@color/ctrl_active_light"/>
<TextView
<net.osmand.telegram.ui.views.TextViewEx
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
@ -90,7 +127,8 @@
android:text="•"
android:textColor="?attr/android:textColorSecondary"
android:textSize="@dimen/list_item_description_text_size"
android:visibility="visible" />
android:visibility="visible"
app:firstBaselineToTopHeight="@dimen/list_item_icon_margin_right" />
</LinearLayout>
@ -103,6 +141,7 @@
android:maxLines="1"
android:textColor="?attr/android:textColorSecondary"
android:textSize="@dimen/list_item_description_text_size"
app:firstBaselineToTopHeight="@dimen/list_item_icon_margin_right"
app:typeface="@string/font_roboto_regular"
tools:text="Live: 1 • All: 36"/>
@ -136,11 +175,12 @@
<net.osmand.telegram.ui.views.TextViewEx
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_height="match_parent"
android:layout_marginEnd="@dimen/content_padding_standard"
android:layout_marginRight="@dimen/content_padding_standard"
android:layout_weight="1"
android:text="@string/show_on_map"
app:firstBaselineToTopHeight="@dimen/list_item_baseline_to_top_height_big"
android:textAppearance="?attr/textAppearanceListItemSecondary"
android:textColor="?android:attr/textColorSecondary"
app:typeface="@string/font_roboto_medium"/>
@ -148,7 +188,8 @@
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/show_on_map_state"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_height="match_parent"
app:firstBaselineToTopHeight="@dimen/list_item_baseline_to_top_height_big"
android:textAppearance="?attr/textAppearanceListItemSecondary"
android:textColor="?attr/ctrl_active_color"
app:typeface="@string/font_roboto_medium"
@ -160,7 +201,6 @@
android:id="@+id/bottom_divider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginBottom="@dimen/card_divider_bottom_margin"
android:layout_marginLeft="@dimen/list_item_content_margin"
android:layout_marginStart="@dimen/list_item_content_margin"
android:background="?attr/card_divider_color"/>

View file

@ -31,6 +31,8 @@
<color name="card_divider_light">#f0f0f0</color>
<color name="card_divider_dark">#2d3133</color>
<color name="app_bar_divider">#e2e2e2</color>
<color name="primary_btn_text_light">#ffffff</color>
<color name="primary_btn_text_dark">#cccccc</color>

View file

@ -29,6 +29,7 @@
<dimen name="list_item_height_min">48dp</dimen>
<dimen name="list_item_height_big">64dp</dimen>
<dimen name="list_item_icon_size_small">14dp</dimen>
<dimen name="list_item_icon_size">40dp</dimen>
<dimen name="list_item_icon_margin_left">12dp</dimen>
<dimen name="list_item_icon_margin_right">20dp</dimen>
@ -36,6 +37,10 @@
<dimen name="list_item_content_margin">72dp</dimen>
<dimen name="list_item_bottom_margin">3dp</dimen>
<dimen name="list_item_baseline_to_top_height_small">20dp</dimen>
<dimen name="list_item_baseline_to_top_height">24dp</dimen>
<dimen name="list_item_baseline_to_top_height_big">28dp</dimen>
<dimen name="list_view_bottom_padding">52dp</dimen>
<dimen name="card_divider_bottom_margin">6dp</dimen>

View file

@ -1,4 +1,10 @@
<resources>
<string name="shared_string_name">Name</string>
<string name="by_distance">By distance</string>
<string name="by_name">By name</string>
<string name="by_group">By group</string>
<string name="shared_string_sort">Sort</string>
<string name="shared_string_sort_by">Sort by</string>
<string name="choose_osmand_desc">Select OsmAnd version where contacts will be displayed on the map.</string>
<string name="choose_osmand">Select OsmAnd version to use</string>
<string name="disable_all_sharing_desc">It will disable sharing your location to all selected chats (%1$d).</string>

View file

@ -49,6 +49,8 @@ private const val DEFAULT_VISIBLE_TIME_SECONDS = 60 * 60L // 1 hour
private const val TITLES_REPLACED_WITH_IDS = "changed_to_chat_id"
private const val LIVE_NOW_SORT_TYPE_KEY = "live_now_sort_type"
class TelegramSettings(private val app: TelegramApplication) {
private var chatLivePeriods = mutableMapOf<Long, Long>()
@ -67,6 +69,8 @@ class TelegramSettings(private val app: TelegramApplication) {
var appToConnectPackage = ""
private set
var liveNowSortType = LiveNowSortType.SORT_BY_GROUP
val gpsAndLocPrefs = listOf(SendMyLocPref(), StaleLocPref(), LocHistoryPref())
init {
@ -211,6 +215,8 @@ class TelegramSettings(private val app: TelegramApplication) {
edit.putString(APP_TO_CONNECT_PACKAGE_KEY, appToConnectPackage)
edit.putString(LIVE_NOW_SORT_TYPE_KEY, liveNowSortType.name)
edit.apply()
}
@ -246,6 +252,8 @@ class TelegramSettings(private val app: TelegramApplication) {
locHistoryTime = prefs.getLong(LOC_HISTORY_TIME_KEY, locHistoryDef)
appToConnectPackage = prefs.getString(APP_TO_CONNECT_PACKAGE_KEY, "")
liveNowSortType = LiveNowSortType.valueOf(prefs.getString(LIVE_NOW_SORT_TYPE_KEY, LiveNowSortType.SORT_BY_GROUP.name))
}
private fun updatePrefs() {
@ -369,4 +377,24 @@ class TelegramSettings(private val app: TelegramApplication) {
values().filter { AndroidUtils.isAppInstalled(context, it.appPackage) }
}
}
enum class LiveNowSortType(@DrawableRes val iconId: Int, @StringRes val titleId: Int, @StringRes val shortTitleId: Int) {
SORT_BY_GROUP(
R.drawable.ic_action_sort_by_group,
R.string.shared_string_group,
R.string.by_group
),
SORT_BY_NAME(
R.drawable.ic_action_sort_by_name,
R.string.shared_string_name,
R.string.by_name
),
SORT_BY_DISTANCE(
R.drawable.ic_action_sort_by_distance,
R.string.shared_string_distance,
R.string.by_distance
);
fun isSortByGroup() = this == SORT_BY_GROUP
}
}

View file

@ -76,11 +76,11 @@ class ShowLocationHelper(private val app: TelegramApplication) {
val chatId = message.chatId
val chatTitle = telegramHelper.getChat(message.chatId)?.title
val content = message.content
val date = telegramHelper.getLastUpdatedTime(message)
val stale = System.currentTimeMillis() / 1000 - date > app.settings.staleLocTime
if (chatTitle != null && content is TdApi.MessageLocation) {
var userName = ""
var photoPath: String? = null
val date = telegramHelper.getLastUpdatedTime(message)
val stale = System.currentTimeMillis() / 1000 - date > app.settings.staleLocTime
val user = telegramHelper.getUser(message.senderUserId)
if (user != null) {
userName = "${user.firstName} ${user.lastName}".trim()
@ -113,10 +113,10 @@ class ShowLocationHelper(private val app: TelegramApplication) {
setupMapLayer()
if (update) {
osmandAidlHelper.updateMapPoint(MAP_LAYER_ID, "${chatId}_$name", name, name,
chatTitle, Color.WHITE, ALatLon(content.lat, content.lon), null, null)
chatTitle, Color.WHITE, ALatLon(content.lat, content.lon), null, generatePhotoParams(null, stale))
} else {
osmandAidlHelper.addMapPoint(MAP_LAYER_ID, "${chatId}_$name", name, name,
chatTitle, Color.WHITE, ALatLon(content.lat, content.lon), null, null)
chatTitle, Color.WHITE, ALatLon(content.lat, content.lon), null, generatePhotoParams(null, stale))
}
}
}

View file

@ -48,6 +48,7 @@ object TelegramUiHelper {
val res = ChatItem().apply {
chatId = chat.id
chatTitle = chat.title
name = chat.title
photoPath = chat.photo?.small?.local?.path
placeholderId = R.drawable.img_user_picture
}
@ -110,6 +111,19 @@ object TelegramUiHelper {
}
}
fun messageToChatItem(
helper: TelegramHelper,
chat: TdApi.Chat,
message: TdApi.Message
): ChatItem? {
val content = message.content
return when (content) {
is MessageOsmAndBotLocation -> botMessageToChatItem(helper, chat, content)
is TdApi.MessageLocation -> locationMessageToChatItem(helper, chat, message)
else -> null
}
}
private fun botMessageToLocationItem(
chat: TdApi.Chat,
content: MessageOsmAndBotLocation
@ -148,12 +162,63 @@ object TelegramUiHelper {
}
}
private fun botMessageToChatItem(
helper: TelegramHelper,
chat: TdApi.Chat,
content: MessageOsmAndBotLocation
): ChatItem? {
return if (content.isValid()) {
ChatItem().apply {
chatId = chat.id
chatTitle = chat.title
name = content.name
latLon = LatLon(content.lat, content.lon)
photoPath = chat.photo?.small?.local?.path
placeholderId = R.drawable.img_user_picture
privateChat = helper.isPrivateChat(chat) || helper.isSecretChat(chat)
lastUpdated = content.lastUpdated
chatWithBot = true
}
} else {
null
}
}
private fun locationMessageToChatItem(
helper: TelegramHelper,
chat: TdApi.Chat,
message: TdApi.Message
): ChatItem? {
val user = helper.getUser(message.senderUserId) ?: return null
val content = message.content as TdApi.MessageLocation
return ChatItem().apply {
chatId = chat.id
chatTitle = chat.title
name = TelegramUiHelper.getUserName(user)
latLon = LatLon(content.location.latitude, content.location.longitude)
if (helper.isGroup(chat)) {
photoPath = helper.getUserPhotoPath(user)
groupPhotoPath = chat.photo?.small?.local?.path
} else {
photoPath = chat.photo?.small?.local?.path
}
grayscalePhotoPath = helper.getUserGreyPhotoPath(user)
placeholderId = R.drawable.img_user_picture
userId = message.senderUserId
privateChat = helper.isPrivateChat(chat) || helper.isSecretChat(chat)
chatWithBot = helper.isBot(userId)
lastUpdated = helper.getLastUpdatedTime(message)
}
}
abstract class ListItem {
var chatId: Long = 0
internal set
var chatTitle: String = ""
internal set
var name: String = ""
internal set
var latLon: LatLon? = null
internal set
var photoPath: String? = null
@ -176,6 +241,8 @@ object TelegramUiHelper {
class ChatItem : ListItem() {
var groupPhotoPath: String? = null
internal set
var privateChat: Boolean = false
internal set
var chatWithBot: Boolean = false
@ -185,7 +252,7 @@ object TelegramUiHelper {
var liveMembersCount: Int = 0
internal set
override fun canBeOpenedOnMap() = latLon != null && !chatWithBot
override fun canBeOpenedOnMap() = latLon != null
override fun getMapPointId() = "${chatId}_$userId"
@ -194,9 +261,6 @@ object TelegramUiHelper {
class LocationItem : ListItem() {
var name: String = ""
internal set
override fun canBeOpenedOnMap() = latLon != null
override fun getMapPointId(): String {

View file

@ -13,8 +13,10 @@ import android.view.ViewGroup
import android.view.animation.LinearInterpolator
import android.widget.ArrayAdapter
import android.widget.ImageView
import android.widget.LinearLayout
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.TelegramCompassListener
@ -49,6 +51,7 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
private lateinit var locationViewCache: UpdateLocationViewCache
private lateinit var openOsmAndBtn: TextView
private lateinit var sortByBtn: TextView
private var location: Location? = null
private var heading: Float? = null
@ -80,6 +83,15 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
(activity as MainActivity).setupOptionsBtn(mainView.findViewById<ImageView>(R.id.options))
sortByBtn = mainView.findViewById<TextView>(R.id.sort_button)
updateSortBtn()
mainView.findViewById<LinearLayout>(R.id.sort_by_container).setOnClickListener {
fragmentManager?.also { fm ->
SortByBottomSheet.showInstance(fm, this@LiveNowTabFragment)
}
}
openOsmAndBtn = mainView.findViewById<TextView>(R.id.open_osmand_btn).apply {
setOnClickListener {
val pack = settings.appToConnectPackage
@ -114,8 +126,12 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == ChooseOsmAndBottomSheet.OSMAND_CHOSEN_REQUEST_CODE) {
updateOpenOsmAndIcon()
when (requestCode) {
ChooseOsmAndBottomSheet.OSMAND_CHOSEN_REQUEST_CODE -> updateOpenOsmAndIcon()
SortByBottomSheet.SORTING_CHANGED_REQUEST_CODE -> {
updateSortBtn()
updateList()
}
}
}
@ -248,20 +264,52 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
val res = mutableListOf<ListItem>()
for ((id, messages) in telegramHelper.getMessagesByChatIds(settings.locHistoryTime)) {
telegramHelper.getChat(id)?.also { chat ->
if (settings.liveNowSortType.isSortByGroup()) {
res.add(TelegramUiHelper.chatToChatItem(telegramHelper, chat, messages))
}
val type = chat.type
if (type is TdApi.ChatTypeBasicGroup || type is TdApi.ChatTypeSupergroup) {
res.addAll(convertToLocationItems(chat, messages))
res.addAll(convertToListItems(chat, messages))
} else if (type is TdApi.ChatTypePrivate) {
if (telegramHelper.isOsmAndBot(type.userId)) {
res.addAll(convertToLocationItems(chat, messages))
} else if (messages.firstOrNull { it.viaBotUserId != 0 } != null) {
res.addAll(convertToLocationItems(chat, messages, true))
when {
telegramHelper.isOsmAndBot(type.userId) -> res.addAll(convertToListItems(chat, messages))
messages.firstOrNull { it.viaBotUserId != 0 } != null -> res.addAll(convertToListItems(chat, messages, true))
!settings.liveNowSortType.isSortByGroup() -> res.add(TelegramUiHelper.chatToChatItem(telegramHelper, chat, messages))
}
}
}
}
adapter.items = res
adapter.items = sortAdapterItems(res)
}
private fun sortAdapterItems(list: MutableList<ListItem>): MutableList<ListItem> {
if (settings.liveNowSortType == TelegramSettings.LiveNowSortType.SORT_BY_DISTANCE) {
list.sortWith(java.util.Comparator<ListItem> { lhs, rhs ->
if (location == null) {
return@Comparator 0
}
val loc = LatLon(location!!.latitude, location!!.longitude)
val ld = MapUtils.getDistance(loc, lhs.latLon!!.latitude, lhs.latLon!!.longitude)
val rd = MapUtils.getDistance(loc, rhs.latLon!!.latitude, rhs.latLon!!.longitude)
java.lang.Double.compare(ld, rd)
})
} else if (settings.liveNowSortType == TelegramSettings.LiveNowSortType.SORT_BY_NAME) {
list.sortWith(Comparator<ListItem> { o1, o2 -> o1.name.compareTo(o2.name) })
}
return list
}
private fun convertToListItems(
chat: TdApi.Chat,
messages: List<TdApi.Message>,
addOnlyViaBotMessages: Boolean = false
): List<ListItem> {
return if (settings.liveNowSortType.isSortByGroup()) {
convertToLocationItems(chat, messages, addOnlyViaBotMessages)
} else {
convertToChatItems(chat, messages, addOnlyViaBotMessages)
}
}
private fun convertToLocationItems(
@ -280,6 +328,22 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
return res
}
private fun convertToChatItems(
chat: TdApi.Chat,
messages: List<TdApi.Message>,
addOnlyViaBotMessages: Boolean = false
): List<ChatItem> {
val res = mutableListOf<ChatItem>()
messages.forEach { message ->
if (!addOnlyViaBotMessages || message.viaBotUserId != 0) {
TelegramUiHelper.messageToChatItem(telegramHelper, chat, message)?.also {
res.add(it)
}
}
}
return res
}
private fun showOsmAndMissingDialog() {
activity?.let {
MainActivity.OsmandMissingDialogFragment().show(it.supportFragmentManager, null)
@ -301,6 +365,16 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
return AndroidUtils.isAppInstalled(ctx, settings.appToConnectPackage)
}
private fun updateSortBtn() {
sortByBtn.text = getString(settings.liveNowSortType.shortTitleId)
sortByBtn.setCompoundDrawablesWithIntrinsicBounds(
null,
null,
app.uiUtils.getActiveIcon(settings.liveNowSortType.iconId),
null
)
}
inner class LiveNowListAdapter : RecyclerView.Adapter<BaseViewHolder>() {
private var lastResponseStr = getString(R.string.last_response) + ": "
@ -336,17 +410,23 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
val lastItem = position == itemCount - 1
val item = items[position]
val sortByGroup = settings.liveNowSortType.isSortByGroup()
val canBeOpenedOnMap = item.canBeOpenedOnMap()
val openOnMapView = holder.getOpenOnMapClickView()
val staleLocation = System.currentTimeMillis() / 1000 - item.lastUpdated > settings.staleLocTime
if (staleLocation) {
TelegramUiHelper.setupPhoto(app, holder.icon, item.grayscalePhotoPath, item.placeholderId, false)
val photoPath = if (sortByGroup && item is ChatItem && !item.privateChat) {
item.photoPath
} else {
item.grayscalePhotoPath
}
TelegramUiHelper.setupPhoto(app, holder.icon, photoPath, item.placeholderId, false)
} else {
TelegramUiHelper.setupPhoto(app, holder.icon, item.photoPath, R.drawable.img_user_picture_active, false)
}
holder.title?.text = item.getVisibleName()
holder.title?.text = if (sortByGroup) item.getVisibleName() else item.name
openOnMapView?.isEnabled = canBeOpenedOnMap
if (canBeOpenedOnMap) {
openOnMapView?.setOnClickListener {
@ -374,15 +454,26 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
holder.bottomShadow?.visibility = if (lastItem) View.VISIBLE else View.GONE
if (item is ChatItem && holder is ChatViewHolder) {
val nextIsLocation = !lastItem && items[position + 1] is LocationItem
val nextIsLocation = !lastItem && (items[position + 1] is LocationItem || !sortByGroup)
val chatId = item.chatId
val stateTextInd = if (settings.isShowingChatOnMap(chatId)) 1 else 0
val groupDescrRowVisible = !sortByGroup
&& (!item.privateChat || item.chatWithBot)
if (groupDescrRowVisible) {
holder.groupDescrContainer?.visibility = View.VISIBLE
holder.groupTitle?.text = item.getVisibleName()
TelegramUiHelper.setupPhoto(app, holder.groupImage, item.groupPhotoPath, item.placeholderId, false)
} else {
holder.groupDescrContainer?.visibility = View.GONE
}
holder.description?.text = getChatItemDescription(item)
holder.imageButton?.visibility = View.GONE
holder.showOnMapRow?.setOnClickListener { showPopupMenu(holder, chatId) }
holder.showOnMapState?.text = menuList[stateTextInd]
holder.bottomDivider?.visibility = if (nextIsLocation) View.VISIBLE else View.GONE
holder.topDivider?.visibility = if (!sortByGroup && position != 0) View.GONE else View.VISIBLE
} else if (item is LocationItem && holder is ContactViewHolder) {
holder.description?.text = OsmandFormatter.getListItemLiveTimeDescr(app, item.lastUpdated, lastResponseStr)
}
@ -392,13 +483,23 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
private fun getChatItemDescription(item: ChatItem): String {
return when {
item.chatWithBot -> getString(R.string.shared_string_bot)
item.privateChat -> { OsmandFormatter.getListItemLiveTimeDescr(app, item.lastUpdated, lastResponseStr) }
item.chatWithBot -> {
if (settings.liveNowSortType.isSortByGroup()) {
getString(R.string.shared_string_bot)
} else {
OsmandFormatter.getListItemLiveTimeDescr(app, item.lastUpdated, lastResponseStr)
}
}
item.privateChat -> OsmandFormatter.getListItemLiveTimeDescr(app, item.lastUpdated, lastResponseStr)
else -> {
if (settings.liveNowSortType.isSortByGroup()) {
val live = getString(R.string.shared_string_live)
val all = getString(R.string.shared_string_all)
val liveStr = "$live ${item.liveMembersCount}"
if (item.membersCount > 0) "$liveStr$all ${item.membersCount}" else liveStr
} else {
OsmandFormatter.getListItemLiveTimeDescr(app, item.lastUpdated, lastResponseStr)
}
}
}
}
@ -463,9 +564,13 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
inner class ChatViewHolder(view: View) : BaseViewHolder(view) {
val userRow: View? = view.findViewById(R.id.user_row)
val groupDescrContainer: View? = view.findViewById(R.id.group_container)
val groupImage: ImageView? = view.findViewById(R.id.group_icon)
val groupTitle: TextView? = view.findViewById(R.id.group_title)
val imageButton: ImageView? = view.findViewById(R.id.image_button)
val showOnMapRow: View? = view.findViewById(R.id.show_on_map_row)
val showOnMapState: TextView? = view.findViewById(R.id.show_on_map_state)
val topDivider: View? = view.findViewById(R.id.top_divider)
val bottomDivider: View? = view.findViewById(R.id.bottom_divider)
override fun getOpenOnMapClickView() = userRow

View file

@ -0,0 +1,104 @@
package net.osmand.telegram.ui
import android.os.Bundle
import android.support.design.widget.BottomSheetBehavior
import android.support.v4.app.DialogFragment
import android.support.v4.app.Fragment
import android.support.v4.app.FragmentManager
import android.support.v4.content.ContextCompat
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import net.osmand.telegram.R
import net.osmand.telegram.TelegramApplication
import net.osmand.telegram.TelegramSettings
import net.osmand.telegram.ui.views.BottomSheetDialog
class SortByBottomSheet : DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?) = BottomSheetDialog(context!!)
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val app = activity?.application as TelegramApplication
val mainView = inflater.inflate(R.layout.bottom_sheet_sort_by, container, false)
mainView.findViewById<View>(R.id.scroll_view_container).setOnClickListener { dismiss() }
BottomSheetBehavior.from(mainView.findViewById<View>(R.id.scroll_view))
.setBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
override fun onStateChanged(bottomSheet: View, newState: Int) {
if (newState == BottomSheetBehavior.STATE_HIDDEN) {
dismiss()
}
}
override fun onSlide(bottomSheet: View, slideOffset: Float) {}
})
val itemsCont = mainView.findViewById<ViewGroup>(R.id.items_container)
for (sortType in TelegramSettings.LiveNowSortType.values()) {
inflater.inflate(R.layout.item_with_rb_and_btn, itemsCont, false).apply {
val currentType = sortType == app.settings.liveNowSortType
val image = if (currentType) {
app.uiUtils.getActiveIcon(sortType.iconId)
} else {
app.uiUtils.getThemedIcon(sortType.iconId)
}
findViewById<ImageView>(R.id.icon).setImageDrawable(image)
findViewById<TextView>(R.id.title)?.apply {
text = getText(sortType.titleId)
val colorId = if (currentType) R.color.ctrl_active_light else R.color.primary_text_light
setTextColor(ContextCompat.getColor(app, colorId))
}
findViewById<View>(R.id.primary_btn_container).visibility = View.GONE
findViewById<View>(R.id.radio_button).visibility = View.GONE
setOnClickListener {
app.settings.liveNowSortType = sortType
targetFragment?.also { target ->
target.onActivityResult(targetRequestCode, SORTING_CHANGED_REQUEST_CODE, null)
}
dismiss()
}
itemsCont.addView(this)
}
}
mainView.findViewById<TextView>(R.id.secondary_btn).apply {
setText(R.string.shared_string_cancel)
setOnClickListener { dismiss() }
}
return mainView
}
companion object {
const val SORTING_CHANGED_REQUEST_CODE = 3
private const val TAG = "SortByBottomSheet"
fun showInstance(
fm: FragmentManager,
target: Fragment
): Boolean {
return try {
SortByBottomSheet().apply {
setTargetFragment(target, SORTING_CHANGED_REQUEST_CODE)
show(fm, TAG)
}
true
} catch (e: RuntimeException) {
false
}
}
}
}