Search initial commit
This commit is contained in:
parent
688d193803
commit
fca39521cc
15 changed files with 946 additions and 74 deletions
21
OsmAnd-telegram/res/drawable/gradient_both_sides_light.xml
Normal file
21
OsmAnd-telegram/res/drawable/gradient_both_sides_light.xml
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<gradient
|
||||
android:angle="0"
|
||||
android:centerColor="#00ffffff"
|
||||
android:centerX="0.2"
|
||||
android:startColor="@color/card_bg_light" />
|
||||
</shape>
|
||||
</item>
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<gradient
|
||||
android:angle="180"
|
||||
android:centerColor="#00ffffff"
|
||||
android:centerX="0.2"
|
||||
android:startColor="@color/card_bg_light" />
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
|
@ -28,34 +28,10 @@
|
|||
|
||||
</android.support.design.widget.CoordinatorLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/buttons_bar"
|
||||
<include
|
||||
layout="@layout/bottom_buttons_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/buttons_bottom_bar_height"
|
||||
android:background="?attr/card_bg_color"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingLeft="@dimen/content_padding_half"
|
||||
android:paddingRight="@dimen/content_padding_half"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible">
|
||||
|
||||
<include
|
||||
layout="@layout/secondary_btn"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"/>
|
||||
|
||||
<View
|
||||
android:layout_width="@dimen/content_padding_half"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
<include
|
||||
layout="@layout/primary_btn"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"/>
|
||||
|
||||
</LinearLayout>
|
||||
android:layout_height="@dimen/buttons_bottom_bar_height" />
|
||||
|
||||
<android.support.design.widget.BottomNavigationView
|
||||
android:id="@+id/bottom_navigation"
|
||||
|
|
30
OsmAnd-telegram/res/layout/bottom_buttons_bar.xml
Normal file
30
OsmAnd-telegram/res/layout/bottom_buttons_bar.xml
Normal file
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/buttons_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/buttons_bottom_bar_height"
|
||||
android:background="?attr/card_bg_color"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingLeft="@dimen/content_padding_half"
|
||||
android:paddingRight="@dimen/content_padding_half"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible">
|
||||
|
||||
<include
|
||||
layout="@layout/secondary_btn"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<View
|
||||
android:layout_width="@dimen/content_padding_half"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<include
|
||||
layout="@layout/primary_btn"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1" />
|
||||
|
||||
</LinearLayout>
|
67
OsmAnd-telegram/res/layout/empty_state_search.xml
Normal file
67
OsmAnd-telegram/res/layout/empty_state_search.xml
Normal file
|
@ -0,0 +1,67 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:osmand="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/empty_state_image_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/my_location_image_height"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:foreground="@drawable/gradient_both_sides_light">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/empty_state_background"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scaleType="center"
|
||||
android:src="@drawable/img_my_location_roadbg" />
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="@dimen/content_padding_standard">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/empty_state_placeholder"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/img_my_location_user" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/empty_state_user_icon"
|
||||
android:layout_width="@dimen/my_location_user_icon_size"
|
||||
android:layout_height="@dimen/my_location_user_icon_size"
|
||||
android:layout_gravity="center"
|
||||
android:src="@drawable/img_user_placeholder" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<net.osmand.telegram.ui.views.TextViewEx
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/content_padding_half"
|
||||
android:background="@null"
|
||||
android:text="@string/search_contacts"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:textSize="20sp"
|
||||
osmand:typeface="@string/font_roboto_medium" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="68dp"
|
||||
android:layout_marginRight="68dp"
|
||||
android:background="@null"
|
||||
android:gravity="center"
|
||||
android:text="@string/search_contacts_descr"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:textSize="18sp" />
|
||||
|
||||
</LinearLayout>
|
|
@ -101,49 +101,6 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/search_box"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/content_padding_half"
|
||||
android:layout_marginRight="@dimen/content_padding_half"
|
||||
android:visibility="gone"
|
||||
tools:background="@drawable/btn_round">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/search_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/search_box_height"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/search_hint"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/content_padding_standard"
|
||||
android:layout_marginRight="@dimen/content_padding_standard"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_vertical"
|
||||
android:maxLines="1"
|
||||
android:text="@string/my_location_search_hint"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:textSize="@dimen/descr_text_size"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/search_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/content_padding_half"
|
||||
android:layout_marginRight="@dimen/content_padding_half"
|
||||
tools:src="@drawable/ic_action_search_dark"
|
||||
tools:tint="@color/icon_light"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/title_container"
|
||||
android:layout_width="match_parent"
|
||||
|
@ -296,6 +253,48 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/search_box"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/content_padding_half"
|
||||
android:layout_marginRight="@dimen/content_padding_half"
|
||||
tools:background="@drawable/btn_round">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/search_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/search_box_height"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/search_hint"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/content_padding_standard"
|
||||
android:layout_marginRight="@dimen/content_padding_standard"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_vertical"
|
||||
android:maxLines="1"
|
||||
android:text="@string/my_location_search_hint"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:textSize="@dimen/descr_text_size"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/search_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/content_padding_half"
|
||||
android:layout_marginRight="@dimen/content_padding_half"
|
||||
tools:src="@drawable/ic_action_search_dark"
|
||||
tools:tint="@color/icon_light"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</android.support.design.widget.AppBarLayout>
|
||||
|
||||
<FrameLayout
|
||||
|
|
92
OsmAnd-telegram/res/layout/fragment_search_dialog.xml
Normal file
92
OsmAnd-telegram/res/layout/fragment_search_dialog.xml
Normal file
|
@ -0,0 +1,92 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<android.support.design.widget.AppBarLayout
|
||||
android:id="@+id/app_bar_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/card_bg_color">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/action_bar_height">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/title_row"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/searchEditText"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/content_padding_standard"
|
||||
android:layout_marginRight="@dimen/content_padding_standard"
|
||||
android:layout_weight="1"
|
||||
android:background="@null"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_vertical"
|
||||
android:hint="@string/type_contact_or_group_name"
|
||||
android:maxLines="1"
|
||||
android:textColor="@color/app_bar_title_light"
|
||||
android:textSize="@dimen/title_text_size" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/search_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:contentDescription="@string/shared_string_search"
|
||||
android:padding="@dimen/content_padding_standard"
|
||||
android:src="@drawable/ic_action_search_dark"
|
||||
android:tint="@color/icon_light" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</android.support.v7.widget.Toolbar>
|
||||
|
||||
</android.support.design.widget.AppBarLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<net.osmand.telegram.ui.views.EmptyStateRecyclerView
|
||||
android:id="@+id/recycler_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:paddingBottom="@dimen/buttons_bottom_bar_height" />
|
||||
|
||||
<include
|
||||
android:id="@+id/empty_view"
|
||||
layout="@layout/empty_state_search" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:orientation="vertical">
|
||||
|
||||
<android.support.v7.widget.AppCompatImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:scaleType="fitXY"
|
||||
android:src="?attr/bottom_nav_shadow" />
|
||||
|
||||
<include
|
||||
layout="@layout/bottom_buttons_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/buttons_bottom_bar_height"
|
||||
android:layout_gravity="bottom" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</LinearLayout>
|
|
@ -7,6 +7,10 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<include
|
||||
android:id="@+id/top_divider"
|
||||
layout="@layout/list_item_divider"/>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="search_contacts">Search contacts</string>
|
||||
<string name="search_contacts_descr">Search across all of your groups and contacts.</string>
|
||||
<string name="type_contact_or_group_name">Type contact or group name</string>
|
||||
<string name="shared_string_search">Search</string>
|
||||
<string name="shared_string_ok">OK</string>
|
||||
<string name="timeline_available_for_free_now">Timeline is a feature available now for free.</string>
|
||||
<string name="disable_monitoring">Disable monitoring</string>
|
||||
|
|
|
@ -35,6 +35,8 @@ class TelegramHelper private constructor() {
|
|||
private const val IGNORED_ERROR_CODE = 406
|
||||
private const val MESSAGE_CANNOT_BE_EDITED_ERROR_CODE = 5
|
||||
|
||||
private const val MAX_SEARCH_ITEMS = 100
|
||||
|
||||
// min and max values for the Telegram API
|
||||
const val MIN_LOCATION_MESSAGE_LIVE_PERIOD_SEC = 61
|
||||
const val MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC = 60 * 60 * 24 - 1 // one day
|
||||
|
@ -98,6 +100,7 @@ class TelegramHelper private constructor() {
|
|||
private val incomingMessagesListeners = HashSet<TelegramIncomingMessagesListener>()
|
||||
private val outgoingMessagesListeners = HashSet<TelegramOutgoingMessagesListener>()
|
||||
private val fullInfoUpdatesListeners = HashSet<FullInfoUpdatesListener>()
|
||||
private val searchListeners = HashSet<TelegramSearchListener>()
|
||||
|
||||
fun addIncomingMessagesListener(listener: TelegramIncomingMessagesListener) {
|
||||
incomingMessagesListeners.add(listener)
|
||||
|
@ -123,6 +126,14 @@ class TelegramHelper private constructor() {
|
|||
fullInfoUpdatesListeners.remove(listener)
|
||||
}
|
||||
|
||||
fun addSearchListener(listener: TelegramSearchListener) {
|
||||
searchListeners.add(listener)
|
||||
}
|
||||
|
||||
fun removeSearchListener(listener: TelegramSearchListener) {
|
||||
searchListeners.remove(listener)
|
||||
}
|
||||
|
||||
fun getChatList(): TreeSet<OrderedChat> {
|
||||
synchronized(chatList) {
|
||||
return TreeSet(chatList.filter { !it.isChannel })
|
||||
|
@ -193,7 +204,7 @@ class TelegramHelper private constructor() {
|
|||
|
||||
fun isSecretChat(chat: TdApi.Chat): Boolean = chat.type is TdApi.ChatTypeSecret
|
||||
|
||||
private fun isChannel(chat: TdApi.Chat): Boolean {
|
||||
fun isChannel(chat: TdApi.Chat): Boolean {
|
||||
return chat.type is TdApi.ChatTypeSupergroup && (chat.type as TdApi.ChatTypeSupergroup).isChannel
|
||||
}
|
||||
|
||||
|
@ -249,6 +260,12 @@ class TelegramHelper private constructor() {
|
|||
fun onTelegramAuthorizationRequestError(code: Int, message: String)
|
||||
}
|
||||
|
||||
interface TelegramSearchListener {
|
||||
fun onSearchChatsFinished(obj: TdApi.Chats)
|
||||
fun onSearchPublicChatsFinished(obj: TdApi.Chats)
|
||||
fun onSearchContactsFinished(obj: TdApi.Users)
|
||||
}
|
||||
|
||||
inner class TelegramAuthorizationRequestHandler(val telegramAuthorizationRequestListener: TelegramAuthorizationRequestListener) {
|
||||
|
||||
fun applyAuthenticationParameter(parameterType: TelegramAuthenticationParameterType, parameterValue: String) {
|
||||
|
@ -628,7 +645,7 @@ class TelegramHelper private constructor() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun requestUser(id: Int) {
|
||||
fun requestUser(id: Int) {
|
||||
client?.send(TdApi.GetUser(id)) { obj ->
|
||||
when (obj.constructor) {
|
||||
TdApi.Error.CONSTRUCTOR -> {
|
||||
|
@ -648,6 +665,24 @@ class TelegramHelper private constructor() {
|
|||
}
|
||||
}
|
||||
|
||||
fun requestChat(id: Long) {
|
||||
client?.send(TdApi.GetChat(id)) { obj ->
|
||||
when (obj.constructor) {
|
||||
TdApi.Error.CONSTRUCTOR -> {
|
||||
val error = obj as TdApi.Error
|
||||
if (error.code != IGNORED_ERROR_CODE) {
|
||||
listener?.onTelegramError(error.code, error.message)
|
||||
}
|
||||
}
|
||||
TdApi.Chat.CONSTRUCTOR -> {
|
||||
val chat = obj as TdApi.Chat
|
||||
chats[chat.id] = chat
|
||||
listener?.onTelegramChatChanged(chat)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun createPrivateChatWithUser(
|
||||
userId: Int,
|
||||
shareInfo: TelegramSettings.ShareChatInfo,
|
||||
|
@ -965,6 +1000,53 @@ class TelegramHelper private constructor() {
|
|||
}
|
||||
}
|
||||
|
||||
fun searchChats(searchTerm: String) {
|
||||
client?.send(TdApi.SearchChats(searchTerm, MAX_SEARCH_ITEMS)) { obj ->
|
||||
checkChatsAndUsersSearch(obj)
|
||||
}
|
||||
}
|
||||
|
||||
fun searchChatsOnServer(searchTerm: String) {
|
||||
client?.send(TdApi.SearchChatsOnServer(searchTerm, MAX_SEARCH_ITEMS)) { obj ->
|
||||
checkChatsAndUsersSearch(obj)
|
||||
}
|
||||
}
|
||||
|
||||
fun searchPublicChats(searchTerm: String) {
|
||||
client?.send(TdApi.SearchPublicChats(searchTerm)) { obj ->
|
||||
checkChatsAndUsersSearch(obj, true)
|
||||
}
|
||||
}
|
||||
|
||||
fun searchContacts(searchTerm: String) {
|
||||
client?.send(TdApi.SearchContacts(searchTerm, MAX_SEARCH_ITEMS)) { obj ->
|
||||
checkChatsAndUsersSearch(obj)
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkChatsAndUsersSearch(obj: TdApi.Object, publicChats: Boolean = false) {
|
||||
when (obj.constructor) {
|
||||
TdApi.Error.CONSTRUCTOR -> {
|
||||
val error = obj as TdApi.Error
|
||||
if (error.code != IGNORED_ERROR_CODE) {
|
||||
listener?.onTelegramError(error.code, error.message)
|
||||
}
|
||||
}
|
||||
TdApi.Chats.CONSTRUCTOR -> {
|
||||
val chats = obj as TdApi.Chats
|
||||
if (publicChats) {
|
||||
searchListeners.forEach { it.onSearchPublicChatsFinished(chats) }
|
||||
} else {
|
||||
searchListeners.forEach { it.onSearchChatsFinished(chats) }
|
||||
}
|
||||
}
|
||||
TdApi.Users.CONSTRUCTOR -> {
|
||||
val users = obj as TdApi.Users
|
||||
searchListeners.forEach { it.onSearchContactsFinished(users) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun logout(): Boolean {
|
||||
return if (libraryLoaded) {
|
||||
haveAuthorization = false
|
||||
|
|
|
@ -510,6 +510,7 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
|
|||
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)
|
||||
holder.topShadowDivider?.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -601,6 +602,7 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
|
|||
val description: TextView? = view.findViewById(R.id.description)
|
||||
val receivedGpxPointsContainer: View? = view.findViewById(R.id.received_gps_points_container)
|
||||
val receivedGpxPointsDescr: TextView? = view.findViewById(R.id.received_gps_points_description)
|
||||
val topShadowDivider: View? = view.findViewById(R.id.top_divider)
|
||||
val bottomShadow: View? = view.findViewById(R.id.bottom_shadow)
|
||||
val lastTelegramUpdateTime: TextView? = view.findViewById(R.id.last_telegram_update_time)
|
||||
|
||||
|
|
|
@ -130,6 +130,7 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
appBarCollapsed = collapsed
|
||||
adjustText()
|
||||
adjustAppbar()
|
||||
adjustSearchBox()
|
||||
optionsBtn.visibility = if (collapsed) View.VISIBLE else View.GONE
|
||||
}
|
||||
})
|
||||
|
@ -183,7 +184,7 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
setBackgroundDrawable(searchBoxBg)
|
||||
}
|
||||
findViewById<View>(R.id.search_button).setOnClickListener {
|
||||
Toast.makeText(context, "Search", Toast.LENGTH_SHORT).show()
|
||||
activity.supportFragmentManager?.also { SearchDialogFragment.showInstance(it, this@MyLocationTabFragment) }
|
||||
}
|
||||
findViewById<ImageView>(R.id.search_icon)
|
||||
.setImageDrawable(app.uiUtils.getThemedIcon(R.drawable.ic_action_search_dark))
|
||||
|
@ -635,6 +636,7 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
}
|
||||
}
|
||||
}
|
||||
holder.topShadowDivider?.visibility = View.GONE
|
||||
holder.bottomShadow?.visibility = if (lastItem) View.VISIBLE else View.GONE
|
||||
holder.itemView.setOnClickListener {
|
||||
if (live) {
|
||||
|
@ -754,6 +756,7 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
|
||||
inner class ChatViewHolder(val view: View) : BaseViewHolder(view) {
|
||||
val checkBox: CheckBox? = view.findViewById(R.id.check_box)
|
||||
val topShadowDivider: View? = view.findViewById(R.id.top_divider)
|
||||
val bottomShadow: View? = view.findViewById(R.id.bottom_shadow)
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,527 @@
|
|||
package net.osmand.telegram.ui
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.graphics.ColorMatrix
|
||||
import android.graphics.ColorMatrixColorFilter
|
||||
import android.os.Bundle
|
||||
import android.support.v4.app.Fragment
|
||||
import android.support.v4.app.FragmentManager
|
||||
import android.support.v7.widget.LinearLayoutManager
|
||||
import android.support.v7.widget.RecyclerView
|
||||
import android.support.v7.widget.Toolbar
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.*
|
||||
import net.osmand.Location
|
||||
import net.osmand.PlatformUtil
|
||||
import net.osmand.data.LatLon
|
||||
import net.osmand.telegram.R
|
||||
import net.osmand.telegram.TelegramLocationProvider.TelegramCompassListener
|
||||
import net.osmand.telegram.TelegramLocationProvider.TelegramLocationListener
|
||||
import net.osmand.telegram.helpers.TelegramHelper
|
||||
import net.osmand.telegram.helpers.TelegramUiHelper
|
||||
import net.osmand.telegram.ui.views.EmptyStateRecyclerView
|
||||
import net.osmand.telegram.utils.AndroidUtils
|
||||
import net.osmand.telegram.utils.OsmandFormatter
|
||||
import net.osmand.telegram.utils.OsmandLocationUtils
|
||||
import net.osmand.telegram.utils.UiUtils
|
||||
import net.osmand.util.MapUtils
|
||||
import org.drinkless.td.libcore.telegram.TdApi
|
||||
|
||||
class SearchDialogFragment : BaseDialogFragment(), TelegramHelper.TelegramSearchListener,
|
||||
TelegramLocationListener, TelegramCompassListener {
|
||||
|
||||
private val log = PlatformUtil.getLog(SearchDialogFragment::class.java)
|
||||
|
||||
private val uiUtils get() = app.uiUtils
|
||||
|
||||
private val adapter = SearchAdapter()
|
||||
|
||||
private lateinit var locationViewCache: UiUtils.UpdateLocationViewCache
|
||||
|
||||
private lateinit var searchBox: EditText
|
||||
private lateinit var buttonsBar: LinearLayout
|
||||
|
||||
private val searchedChatsIds = mutableSetOf<Long>()
|
||||
private val searchedPublicChatsIds = mutableSetOf<Long>()
|
||||
private val searchedContactsIds = mutableSetOf<Int>()
|
||||
|
||||
private val selectedChats = HashSet<Long>()
|
||||
private val selectedUsers = HashSet<Long>()
|
||||
|
||||
private var searchQuery: String = ""
|
||||
|
||||
private var location: Location? = null
|
||||
private var heading: Float? = null
|
||||
private var locationUiUpdateAllowed: Boolean = true
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
parent: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
val mainView = inflater.inflate(R.layout.fragment_search_dialog, parent)
|
||||
|
||||
val appBarLayout = mainView.findViewById<View>(R.id.app_bar_layout)
|
||||
AndroidUtils.addStatusBarPadding19v(context!!, appBarLayout)
|
||||
|
||||
mainView.findViewById<Toolbar>(R.id.toolbar).apply {
|
||||
navigationIcon = uiUtils.getThemedIcon(R.drawable.ic_arrow_back)
|
||||
setNavigationOnClickListener { dismiss() }
|
||||
}
|
||||
|
||||
searchBox = mainView.findViewById<EditText>(R.id.searchEditText).apply {
|
||||
addTextChangedListener(object : TextWatcher {
|
||||
|
||||
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
|
||||
|
||||
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
|
||||
|
||||
override fun afterTextChanged(s: Editable) {
|
||||
val newQueryText = s.toString()
|
||||
if (!searchQuery.equals(newQueryText, true)) {
|
||||
searchQuery = newQueryText
|
||||
clearSearchedItems()
|
||||
if (searchQuery.isNotBlank()) {
|
||||
runSearch()
|
||||
} else {
|
||||
updateList()
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
mainView.findViewById<ImageView>(R.id.search_icon).setOnClickListener {
|
||||
runSearch()
|
||||
}
|
||||
val emptyView = mainView.findViewById<LinearLayout>(R.id.empty_view)
|
||||
mainView.findViewById<EmptyStateRecyclerView>(R.id.recycler_view).apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
adapter = this@SearchDialogFragment.adapter
|
||||
setEmptyView(emptyView)
|
||||
addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
||||
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
|
||||
super.onScrollStateChanged(recyclerView, newState)
|
||||
locationUiUpdateAllowed = newState == RecyclerView.SCROLL_STATE_IDLE
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
val matrix = ColorMatrix()
|
||||
matrix.setSaturation(0f)
|
||||
val filter = ColorMatrixColorFilter(matrix)
|
||||
|
||||
mainView.findViewById<ImageView>(R.id.empty_state_background).colorFilter = filter
|
||||
mainView.findViewById<ImageView>(R.id.empty_state_placeholder).colorFilter = filter
|
||||
|
||||
buttonsBar = mainView.findViewById<LinearLayout>(R.id.buttons_bar).apply {
|
||||
findViewById<TextView>(R.id.primary_btn).apply {
|
||||
text = getString(R.string.shared_string_continue)
|
||||
setOnClickListener {
|
||||
onPrimaryBtnClick()
|
||||
}
|
||||
}
|
||||
findViewById<TextView>(R.id.secondary_btn).apply {
|
||||
text = getString(R.string.shared_string_cancel)
|
||||
setOnClickListener {
|
||||
onSecondaryBtnClick()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mainView
|
||||
}
|
||||
|
||||
private fun clearSearchedItems() {
|
||||
searchedChatsIds.clear()
|
||||
searchedPublicChatsIds.clear()
|
||||
searchedContactsIds.clear()
|
||||
}
|
||||
|
||||
private fun runSearch() {
|
||||
if (searchQuery.isNotBlank()) {
|
||||
runSearch(searchQuery)
|
||||
}
|
||||
}
|
||||
|
||||
private fun runSearch(text: String) {
|
||||
telegramHelper.searchChats(text)
|
||||
telegramHelper.searchChatsOnServer(text)
|
||||
telegramHelper.searchContacts(text)
|
||||
if (text.length > 4) {
|
||||
telegramHelper.searchPublicChats(text)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
telegramHelper.addSearchListener(this)
|
||||
locationViewCache = app.uiUtils.getUpdateLocationViewCache()
|
||||
startLocationUpdate()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
telegramHelper.removeSearchListener(this)
|
||||
stopLocationUpdate()
|
||||
}
|
||||
|
||||
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 { updateList() }
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateList() {
|
||||
val items: MutableList<TdApi.Object> = mutableListOf()
|
||||
val currentUserId = telegramHelper.getCurrentUserId()
|
||||
|
||||
val chats: MutableList<TdApi.Chat> = getChats(currentUserId)
|
||||
items.addAll(chats)
|
||||
|
||||
val users: MutableList<TdApi.User> = getContacts(currentUserId, chats)
|
||||
items.addAll(sortUsers(users))
|
||||
|
||||
items.addAll(getChats(currentUserId, chats))
|
||||
|
||||
adapter.items = items
|
||||
}
|
||||
|
||||
private fun getChats(
|
||||
currentUserId: Int,
|
||||
addedChats: List<TdApi.Chat>? = null
|
||||
): MutableList<TdApi.Chat> {
|
||||
val chats: MutableList<TdApi.Chat> = mutableListOf()
|
||||
searchedChatsIds.forEach {
|
||||
val chat = telegramHelper.getChat(it)
|
||||
if (chat != null) {
|
||||
if (!telegramHelper.isChannel(chat)
|
||||
&& telegramHelper.getUserIdFromChatType(chat.type) != currentUserId
|
||||
&& (addedChats == null || (!addedChats.contains(chat)))
|
||||
) {
|
||||
chats.add(chat)
|
||||
}
|
||||
} else {
|
||||
telegramHelper.requestChat(it)
|
||||
}
|
||||
}
|
||||
return chats
|
||||
}
|
||||
|
||||
private fun getContacts(currentUserId: Int, chats: List<TdApi.Chat>): MutableList<TdApi.User> {
|
||||
val users: MutableList<TdApi.User> = mutableListOf()
|
||||
searchedContactsIds.forEach { userId ->
|
||||
val user = telegramHelper.getUser(userId)
|
||||
if (user != null) {
|
||||
if (user.id != currentUserId && !chats.any { telegramHelper.getUserIdFromChatType(it.type) == user.id })
|
||||
users.add(user)
|
||||
} else {
|
||||
telegramHelper.requestUser(userId)
|
||||
}
|
||||
}
|
||||
return users
|
||||
}
|
||||
|
||||
private fun sortUsers(list: MutableList<TdApi.User>): MutableList<TdApi.User> {
|
||||
list.sortWith(Comparator { o1, o2 ->
|
||||
val title1 = TelegramUiHelper.getUserName(o1)
|
||||
val title2 = TelegramUiHelper.getUserName(o2)
|
||||
title1.compareTo(title2)
|
||||
})
|
||||
return list
|
||||
}
|
||||
|
||||
override fun onSearchContactsFinished(obj: TdApi.Users) {
|
||||
log.debug("searchContactsFinished $obj")
|
||||
val ids = obj.userIds
|
||||
if (ids.isNotEmpty()) {
|
||||
searchedContactsIds.addAll(ids.toList())
|
||||
app.runInUIThread { updateList() }
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSearchChatsFinished(obj: TdApi.Chats) {
|
||||
log.debug("searchChatsFinished $obj")
|
||||
val ids = obj.chatIds
|
||||
if (ids.isNotEmpty()) {
|
||||
searchedChatsIds.addAll(ids.toList())
|
||||
app.runInUIThread { updateList() }
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSearchPublicChatsFinished(obj: TdApi.Chats) {
|
||||
log.debug("onSearchPublicChatsFinished $obj")
|
||||
val ids = obj.chatIds
|
||||
if (ids.isNotEmpty()) {
|
||||
searchedPublicChatsIds.addAll(ids.toList())
|
||||
app.runInUIThread { updateList() }
|
||||
}
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
when (requestCode) {
|
||||
LogoutBottomSheet.LOGOUT_REQUEST_CODE -> {
|
||||
dismiss()
|
||||
}
|
||||
SetTimeDialogFragment.LOCATION_SHARED_REQUEST_CODE -> {
|
||||
if (resultCode == SetTimeDialogFragment.LOCATION_SHARED_REQUEST_CODE) {
|
||||
targetFragment?.also {
|
||||
it.onActivityResult(targetRequestCode, resultCode, null)
|
||||
}
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inner class SearchAdapter : RecyclerView.Adapter<SearchAdapter.ChatViewHolder>() {
|
||||
|
||||
var items = mutableListOf<TdApi.Object>()
|
||||
set(value) {
|
||||
field = value
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChatViewHolder {
|
||||
val view = LayoutInflater.from(parent.context).inflate(R.layout.user_list_item, parent, false)
|
||||
return ChatViewHolder(view)
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun onBindViewHolder(holder: ChatViewHolder, position: Int) {
|
||||
val item = items[position]
|
||||
val isChat = item is TdApi.Chat
|
||||
val itemId = if (isChat) {
|
||||
(item as TdApi.Chat).id
|
||||
} else {
|
||||
(item as TdApi.User).id.toLong()
|
||||
}
|
||||
val latLon = getItemLastLocation(item)
|
||||
val lastUpdate = getLastUpdateTime(item)
|
||||
|
||||
val lastItem = position == itemCount - 1
|
||||
val placeholderId = if (isChat && telegramHelper.isGroup(item as TdApi.Chat)) R.drawable.img_group_picture else R.drawable.img_user_picture
|
||||
val live = (isChat && settings.isSharingLocationToChat(itemId))
|
||||
val shareInfo = if (isChat) settings.getChatsShareInfo()[itemId] else null
|
||||
|
||||
val photoPath = when (item) {
|
||||
is TdApi.Chat -> item.photo?.small?.local?.path
|
||||
is TdApi.User -> item.profilePhoto?.small?.local?.path
|
||||
else -> null
|
||||
}
|
||||
|
||||
TelegramUiHelper.setupPhoto(app, holder.icon, photoPath, placeholderId, false)
|
||||
|
||||
val title = when (item) {
|
||||
is TdApi.Chat -> item.title
|
||||
is TdApi.User -> TelegramUiHelper.getUserName(item)
|
||||
else -> null
|
||||
}
|
||||
|
||||
holder.title?.text = title
|
||||
|
||||
holder.checkBox?.apply {
|
||||
visibility = if (live) View.GONE else View.VISIBLE
|
||||
setOnCheckedChangeListener(null)
|
||||
isChecked = if (isChat) {
|
||||
selectedChats.contains(itemId)
|
||||
} else {
|
||||
selectedUsers.contains(itemId)
|
||||
}
|
||||
setOnCheckedChangeListener { _, isChecked ->
|
||||
if (isChecked) {
|
||||
if (isChat) {
|
||||
selectedChats.add(itemId)
|
||||
} else {
|
||||
selectedUsers.add(itemId)
|
||||
}
|
||||
} else {
|
||||
if (isChat) {
|
||||
selectedChats.remove(itemId)
|
||||
} else {
|
||||
selectedUsers.remove(itemId)
|
||||
}
|
||||
}
|
||||
switchButtonsVisibility(selectedChats.isNotEmpty() || selectedUsers.isNotEmpty())
|
||||
}
|
||||
}
|
||||
holder.topShadowDivider?.visibility = if (position == 0) View.VISIBLE else View.GONE
|
||||
holder.bottomShadow?.visibility = if (lastItem) View.VISIBLE else View.GONE
|
||||
holder.itemView.setOnClickListener {
|
||||
if (!live) {
|
||||
holder.checkBox?.apply {
|
||||
isChecked = !isChecked
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (location != null && latLon != null && lastUpdate != null) {
|
||||
val staleLocation = System.currentTimeMillis() / 1000 - lastUpdate > settings.staleLocTime
|
||||
|
||||
holder.locationViewContainer?.visibility = if (lastUpdate > 0) View.VISIBLE else View.GONE
|
||||
locationViewCache.outdatedLocation = staleLocation
|
||||
app.uiUtils.updateLocationView(holder.directionIcon, holder.distanceText, latLon, locationViewCache)
|
||||
} else {
|
||||
holder.locationViewContainer?.visibility = View.GONE
|
||||
}
|
||||
|
||||
val expiresIn = shareInfo?.getChatLiveMessageExpireTime() ?: 0
|
||||
holder.textInArea?.apply {
|
||||
visibility = if (live) View.VISIBLE else View.GONE
|
||||
text = OsmandFormatter.getFormattedDuration(app, expiresIn)
|
||||
}
|
||||
|
||||
holder.description?.apply {
|
||||
val description = getItemDescription(item, lastUpdate)
|
||||
text = description
|
||||
visibility = if (description != null) View.VISIBLE else View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
private fun getItemLastMessage(item: TdApi.Object): TdApi.Message? {
|
||||
when (item) {
|
||||
is TdApi.User -> {
|
||||
return telegramHelper.getUserMessage(item)
|
||||
}
|
||||
is TdApi.Chat -> {
|
||||
return telegramHelper.getChatMessages(item.id).firstOrNull() ?: item.lastMessage
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun getItemLastLocation(item: TdApi.Object): LatLon? {
|
||||
val message = getItemLastMessage(item)
|
||||
if (message != null && OsmandLocationUtils.getSenderMessageId(message) != telegramHelper.getCurrentUserId()) {
|
||||
val messageLocation = OsmandLocationUtils.parseMessageContent(message, telegramHelper)
|
||||
if (messageLocation != null) {
|
||||
return LatLon(messageLocation.lat, messageLocation.lon)
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun getLastUpdateTime(item: TdApi.Object): Int? {
|
||||
val message = getItemLastMessage(item)
|
||||
if (message != null && OsmandLocationUtils.getSenderMessageId(message) != telegramHelper.getCurrentUserId()) {
|
||||
return OsmandLocationUtils.getLastUpdatedTime(message)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
private fun getItemDescription(item: TdApi.Object, lastUpdateTime: Int?): String? {
|
||||
if (lastUpdateTime != null) {
|
||||
return OsmandFormatter.getListItemLiveTimeDescr(app, lastUpdateTime)
|
||||
}
|
||||
if (item is TdApi.Chat && telegramHelper.isGroup(item)) {
|
||||
return getString(R.string.shared_string_group)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
override fun getItemCount() = items.size
|
||||
|
||||
inner class ChatViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
val icon: ImageView? = view.findViewById(R.id.icon)
|
||||
val title: TextView? = view.findViewById(R.id.title)
|
||||
val locationViewContainer: View? = view.findViewById(R.id.location_view_container)
|
||||
val directionIcon: ImageView? = view.findViewById(R.id.direction_icon)
|
||||
val distanceText: TextView? = view.findViewById(R.id.distance_text)
|
||||
val description: TextView? = view.findViewById(R.id.description)
|
||||
val checkBox: CheckBox? = view.findViewById(R.id.check_box)
|
||||
val textInArea: TextView? = view.findViewById(R.id.text_in_area)
|
||||
val topShadowDivider: View? = view.findViewById(R.id.top_divider)
|
||||
val bottomShadow: View? = view.findViewById(R.id.bottom_shadow)
|
||||
}
|
||||
}
|
||||
|
||||
private fun onPrimaryBtnClick() {
|
||||
if (selectedChats.isNotEmpty() || selectedUsers.isNotEmpty()) {
|
||||
fragmentManager?.also {
|
||||
SetTimeDialogFragment.showInstance(it, selectedChats, selectedUsers, this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun onSecondaryBtnClick() {
|
||||
clearSelection()
|
||||
adapter.notifyDataSetChanged()
|
||||
adapter.notifyDataSetChanged()
|
||||
switchButtonsVisibility(false)
|
||||
}
|
||||
|
||||
private fun clearSelection() {
|
||||
selectedChats.clear()
|
||||
selectedUsers.clear()
|
||||
}
|
||||
|
||||
private fun switchButtonsVisibility(visible: Boolean) {
|
||||
val buttonsVisibility = if (visible) View.VISIBLE else View.GONE
|
||||
if (buttonsBar.visibility != buttonsVisibility) {
|
||||
buttonsBar.visibility = buttonsVisibility
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
const val TAG = "SearchDialogFragment"
|
||||
|
||||
private val SEARCH_ITEM = 1
|
||||
|
||||
fun showInstance(fm: FragmentManager, target: Fragment?): Boolean {
|
||||
return try {
|
||||
SearchDialogFragment().apply {
|
||||
if (target != null) {
|
||||
setTargetFragment(target, SetTimeDialogFragment.LOCATION_SHARED_REQUEST_CODE)
|
||||
}
|
||||
show(fm, TAG)
|
||||
}
|
||||
true
|
||||
} catch (e: RuntimeException) {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -79,6 +79,9 @@ class SetTimeDialogFragment : BaseDialogFragment(), TelegramLocationListener, Te
|
|||
view.findViewById<TextView>(R.id.secondary_btn).apply {
|
||||
text = getString(R.string.shared_string_back)
|
||||
setOnClickListener {
|
||||
targetFragment?.also {
|
||||
it.onActivityResult(targetRequestCode, LOCATION_SHARING_CANCELED_CODE, null)
|
||||
}
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
|
@ -357,6 +360,7 @@ class SetTimeDialogFragment : BaseDialogFragment(), TelegramLocationListener, Te
|
|||
userLivePeriods[itemId]?.also { text = formatLivePeriod(it) }
|
||||
}
|
||||
}
|
||||
holder.topShadowDivider?.visibility = View.GONE
|
||||
holder.bottomShadow?.visibility = View.GONE
|
||||
holder.itemView.setOnClickListener {
|
||||
selectDuration(itemId, isChat)
|
||||
|
@ -373,6 +377,7 @@ class SetTimeDialogFragment : BaseDialogFragment(), TelegramLocationListener, Te
|
|||
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 topShadowDivider: View? = view.findViewById(R.id.top_divider)
|
||||
val bottomShadow: View? = view.findViewById(R.id.bottom_shadow)
|
||||
}
|
||||
}
|
||||
|
@ -380,6 +385,7 @@ class SetTimeDialogFragment : BaseDialogFragment(), TelegramLocationListener, Te
|
|||
companion object {
|
||||
|
||||
const val LOCATION_SHARED_REQUEST_CODE = 0
|
||||
const val LOCATION_SHARING_CANCELED_CODE = 1
|
||||
|
||||
private const val TAG = "SetTimeDialogFragment"
|
||||
private const val CHATS_KEY = "chats_key"
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
package net.osmand.telegram.ui.views
|
||||
|
||||
import android.content.Context
|
||||
import android.support.v7.widget.RecyclerView
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
|
||||
class EmptyStateRecyclerView : RecyclerView {
|
||||
|
||||
private var emptyView: View? = null
|
||||
|
||||
private val emptyStateObserver = object : RecyclerView.AdapterDataObserver() {
|
||||
override fun onChanged() {
|
||||
checkIfEmpty()
|
||||
}
|
||||
|
||||
override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
|
||||
checkIfEmpty()
|
||||
}
|
||||
|
||||
override fun onItemRangeRemoved(positionStart: Int, itemCount: Int) {
|
||||
checkIfEmpty()
|
||||
}
|
||||
}
|
||||
|
||||
constructor(context: Context) : super(context)
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet?, defStyle: Int) : super(
|
||||
context,
|
||||
attrs,
|
||||
defStyle
|
||||
)
|
||||
|
||||
override fun setAdapter(adapter: RecyclerView.Adapter<*>?) {
|
||||
val oldAdapter = getAdapter()
|
||||
oldAdapter?.unregisterAdapterDataObserver(emptyStateObserver)
|
||||
super.setAdapter(adapter)
|
||||
adapter?.registerAdapterDataObserver(emptyStateObserver)
|
||||
checkIfEmpty()
|
||||
}
|
||||
|
||||
fun setEmptyView(emptyView: View) {
|
||||
this.emptyView = emptyView
|
||||
checkIfEmpty()
|
||||
}
|
||||
|
||||
private fun checkIfEmpty() {
|
||||
adapter?.apply {
|
||||
val empty = itemCount == 0
|
||||
visibility = if (empty) View.GONE else View.VISIBLE
|
||||
emptyView?.visibility = if (empty) View.VISIBLE else View.GONE
|
||||
}
|
||||
}
|
||||
}
|
|
@ -169,7 +169,10 @@ object OsmandLocationUtils {
|
|||
}
|
||||
}
|
||||
|
||||
fun parseTextLocation(text: TdApi.FormattedText, botLocation: Boolean): MessageLocation {
|
||||
fun parseTextLocation(text: TdApi.FormattedText, botLocation: Boolean): MessageLocation? {
|
||||
if (botLocation && !text.text.startsWith(DEVICE_PREFIX) || !botLocation && !text.text.startsWith(USER_TEXT_LOCATION_TITLE)) {
|
||||
return null
|
||||
}
|
||||
val res = if (botLocation) MessageOsmAndBotLocation() else MessageUserLocation()
|
||||
res.type = LocationMessages.TYPE_TEXT
|
||||
var locationNA = false
|
||||
|
|
Loading…
Reference in a new issue