Merge pull request #5978 from osmandapp/LiveNowSorting
Live now sorting
This commit is contained in:
commit
561814cf90
11 changed files with 507 additions and 36 deletions
65
OsmAnd-telegram/res/layout/bottom_sheet_sort_by.xml
Normal file
65
OsmAnd-telegram/res/layout/bottom_sheet_sort_by.xml
Normal 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>
|
|
@ -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
|
||||
|
|
|
@ -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"/>
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 ->
|
||||
res.add(TelegramUiHelper.chatToChatItem(telegramHelper, chat, messages))
|
||||
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 -> {
|
||||
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
|
||||
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
|
||||
|
|
104
OsmAnd-telegram/src/net/osmand/telegram/ui/SortByBottomSheet.kt
Normal file
104
OsmAnd-telegram/src/net/osmand/telegram/ui/SortByBottomSheet.kt
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue