commit
c1c2da5335
6 changed files with 477 additions and 45 deletions
103
OsmAnd-telegram/res/layout/last_share_list_item.xml
Normal file
103
OsmAnd-telegram/res/layout/last_share_list_item.xml
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
<?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"
|
||||||
|
android:background="?attr/card_bg_color">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/container"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/selectableItemBackground"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:minHeight="@dimen/list_item_height"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/icon"
|
||||||
|
android:layout_width="@dimen/list_item_icon_size_big"
|
||||||
|
android:layout_height="@dimen/list_item_icon_size_big"
|
||||||
|
android:layout_marginStart="@dimen/list_item_icon_margin_left"
|
||||||
|
android:layout_marginLeft="@dimen/list_item_icon_margin_left"
|
||||||
|
android:layout_marginEnd="@dimen/list_item_icon_margin_right"
|
||||||
|
android:layout_marginRight="@dimen/list_item_icon_margin_right"
|
||||||
|
tools:src="@drawable/img_user_picture" />
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="@dimen/content_padding_half"
|
||||||
|
android:layout_marginRight="@dimen/content_padding_half"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<net.osmand.telegram.ui.views.TextViewEx
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:textColor="?android:textColorPrimary"
|
||||||
|
android:textSize="@dimen/list_item_title_text_size"
|
||||||
|
app:typeface="@string/font_roboto_regular"
|
||||||
|
tools:text="Share to Share Location" />
|
||||||
|
|
||||||
|
<net.osmand.telegram.ui.views.TextViewEx
|
||||||
|
android:id="@+id/time"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
|
android:textSize="@dimen/list_item_description_text_size"
|
||||||
|
app:typeface="@string/font_roboto_regular"
|
||||||
|
tools:text="for 1 hour" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<net.osmand.telegram.ui.views.TextViewEx
|
||||||
|
android:id="@+id/start"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="@dimen/dialog_button_height"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_marginEnd="@dimen/image_button_padding"
|
||||||
|
android:layout_marginRight="@dimen/image_button_padding"
|
||||||
|
android:background="?attr/secondary_btn_bg"
|
||||||
|
android:gravity="center"
|
||||||
|
android:paddingLeft="@dimen/image_button_padding"
|
||||||
|
android:paddingRight="@dimen/image_button_padding"
|
||||||
|
android:text="@string/shared_string_start"
|
||||||
|
android:textColor="?attr/ctrl_active_color"
|
||||||
|
android:textSize="@dimen/text_button_text_size"
|
||||||
|
app:typeface="@string/font_roboto_medium"
|
||||||
|
tools:text="Start" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/divider"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:background="?attr/card_divider_color"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
51
OsmAnd-telegram/res/layout/suggested_list_item.xml
Normal file
51
OsmAnd-telegram/res/layout/suggested_list_item.xml
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
<?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">
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/divider_top"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="26dp" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/container"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/shared_chat_card_bg"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<net.osmand.telegram.ui.views.TextViewEx
|
||||||
|
android:id="@+id/header"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="54dp"
|
||||||
|
android:gravity="start|center_vertical"
|
||||||
|
android:paddingStart="@dimen/content_padding_standard"
|
||||||
|
android:paddingLeft="@dimen/content_padding_half"
|
||||||
|
android:paddingRight="@dimen/content_padding_half"
|
||||||
|
android:text="@string/shared_string_suggested"
|
||||||
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
|
android:textSize="@dimen/hint_text_size"
|
||||||
|
app:typeface="@string/font_roboto_mono_bold"
|
||||||
|
tools:text="Suggested" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/last_items_list"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/divider_bottom"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:background="?attr/card_divider_color"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
|
@ -1,5 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
|
<string name="shared_string_suggested">Suggested</string>
|
||||||
<string name="status_widget_title">OsmAnd Tracker status</string>
|
<string name="status_widget_title">OsmAnd Tracker status</string>
|
||||||
<string name="buffer_time_descr">Maximum time to store points in the buffer</string>
|
<string name="buffer_time_descr">Maximum time to store points in the buffer</string>
|
||||||
<string name="buffer_time">Buffer expiration time</string>
|
<string name="buffer_time">Buffer expiration time</string>
|
||||||
|
|
|
@ -14,13 +14,14 @@ import net.osmand.telegram.helpers.TelegramHelper
|
||||||
import net.osmand.telegram.utils.*
|
import net.osmand.telegram.utils.*
|
||||||
import net.osmand.telegram.utils.OsmandFormatter.MetricsConstants
|
import net.osmand.telegram.utils.OsmandFormatter.MetricsConstants
|
||||||
import net.osmand.telegram.utils.OsmandFormatter.SpeedConstants
|
import net.osmand.telegram.utils.OsmandFormatter.SpeedConstants
|
||||||
import net.osmand.telegram.utils.OsmandLocationUtils
|
|
||||||
import org.drinkless.td.libcore.telegram.TdApi
|
import org.drinkless.td.libcore.telegram.TdApi
|
||||||
import org.json.JSONArray
|
import org.json.JSONArray
|
||||||
import org.json.JSONException
|
import org.json.JSONException
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
|
import java.util.*
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue
|
import java.util.concurrent.ConcurrentLinkedQueue
|
||||||
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
val ADDITIONAL_ACTIVE_TIME_VALUES_SEC = listOf(15 * 60L, 30 * 60L, 60 * 60L, 180 * 60L)
|
val ADDITIONAL_ACTIVE_TIME_VALUES_SEC = listOf(15 * 60L, 30 * 60L, 60 * 60L, 180 * 60L)
|
||||||
|
|
||||||
|
@ -110,6 +111,8 @@ private const val WAITING_TDLIB_TIME = 30 // 2 seconds
|
||||||
|
|
||||||
private const val GPS_UPDATE_EXPIRED_TIME = 60 * 3L // 3 minutes
|
private const val GPS_UPDATE_EXPIRED_TIME = 60 * 3L // 3 minutes
|
||||||
|
|
||||||
|
private const val LAST_CHATS_INFO_KEY = "last_chats_info"
|
||||||
|
|
||||||
class TelegramSettings(private val app: TelegramApplication) {
|
class TelegramSettings(private val app: TelegramApplication) {
|
||||||
|
|
||||||
private val log = PlatformUtil.getLog(TelegramSettings::class.java)
|
private val log = PlatformUtil.getLog(TelegramSettings::class.java)
|
||||||
|
@ -118,6 +121,7 @@ class TelegramSettings(private val app: TelegramApplication) {
|
||||||
private var hiddenOnMapChats: Set<Long> = emptySet()
|
private var hiddenOnMapChats: Set<Long> = emptySet()
|
||||||
private var shareDevices: Set<DeviceBot> = emptySet()
|
private var shareDevices: Set<DeviceBot> = emptySet()
|
||||||
private var liveTracksInfo = emptyList<LiveTrackInfo>()
|
private var liveTracksInfo = emptyList<LiveTrackInfo>()
|
||||||
|
var lastChatsInfo = LinkedList<LastChatInfo>()
|
||||||
|
|
||||||
var sharingStatusChanges = ConcurrentLinkedQueue<SharingStatus>()
|
var sharingStatusChanges = ConcurrentLinkedQueue<SharingStatus>()
|
||||||
|
|
||||||
|
@ -661,6 +665,11 @@ class TelegramSettings(private val app: TelegramApplication) {
|
||||||
edit.putString(LIVE_TRACKS_KEY, jsonArrayLiveTracks.toString())
|
edit.putString(LIVE_TRACKS_KEY, jsonArrayLiveTracks.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val jArrayLastInfo = convertLastChatsInfoToJson()
|
||||||
|
if (jArrayLastInfo != null) {
|
||||||
|
edit.putString(LAST_CHATS_INFO_KEY, jArrayLastInfo.toString())
|
||||||
|
}
|
||||||
|
|
||||||
edit.apply()
|
edit.apply()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -688,6 +697,12 @@ class TelegramSettings(private val app: TelegramApplication) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
parseLastChatsInfo(JSONArray(prefs.getString(LAST_CHATS_INFO_KEY, "")))
|
||||||
|
} catch (e: JSONException) {
|
||||||
|
log.error(e)
|
||||||
|
}
|
||||||
|
|
||||||
parseShareDevices(prefs.getString(SHARE_DEVICES_KEY, ""))
|
parseShareDevices(prefs.getString(SHARE_DEVICES_KEY, ""))
|
||||||
|
|
||||||
val sendMyLocDef = SEND_MY_LOC_VALUES_SEC[SEND_MY_LOC_DEFAULT_INDEX]
|
val sendMyLocDef = SEND_MY_LOC_VALUES_SEC[SEND_MY_LOC_DEFAULT_INDEX]
|
||||||
|
@ -830,6 +845,37 @@ class TelegramSettings(private val app: TelegramApplication) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun convertLastChatsInfoToJson(): JSONArray? {
|
||||||
|
return try {
|
||||||
|
val jArray = JSONArray()
|
||||||
|
lastChatsInfo.forEach { lastInfo ->
|
||||||
|
val obj = JSONObject()
|
||||||
|
obj.put(LastChatInfo.CHAT_ID_KEY, lastInfo.chatId)
|
||||||
|
obj.put(LastChatInfo.PERIODS_KEY, convertPeriodsToJson(lastInfo.periods))
|
||||||
|
jArray.put(obj)
|
||||||
|
}
|
||||||
|
jArray
|
||||||
|
} catch (e: JSONException) {
|
||||||
|
log.error(e)
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun convertPeriodsToJson(periods: LinkedList<Long>): JSONArray? {
|
||||||
|
return try {
|
||||||
|
val jArray = JSONArray()
|
||||||
|
for (i in 0 until periods.count()) {
|
||||||
|
val obj = JSONObject()
|
||||||
|
obj.put(i.toString(), periods[i])
|
||||||
|
jArray.put(obj)
|
||||||
|
}
|
||||||
|
jArray
|
||||||
|
} catch (e: JSONException) {
|
||||||
|
log.error(e)
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun parseShareChatsInfo(json: JSONArray) {
|
private fun parseShareChatsInfo(json: JSONArray) {
|
||||||
for (i in 0 until json.length()) {
|
for (i in 0 until json.length()) {
|
||||||
val obj = json.getJSONObject(i)
|
val obj = json.getJSONObject(i)
|
||||||
|
@ -896,6 +942,71 @@ class TelegramSettings(private val app: TelegramApplication) {
|
||||||
shareDevices = OsmandApiUtils.parseJsonContents(json).toHashSet()
|
shareDevices = OsmandApiUtils.parseJsonContents(json).toHashSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun parseLastChatsInfo(json: JSONArray) {
|
||||||
|
for (i in 0 until json.length()) {
|
||||||
|
val obj = json.getJSONObject(i)
|
||||||
|
val lastInfo = LastChatInfo().apply {
|
||||||
|
chatId = obj.optLong(LastChatInfo.CHAT_ID_KEY)
|
||||||
|
periods = LinkedList<Long>()
|
||||||
|
val jsonArray = obj.getJSONArray(LastChatInfo.PERIODS_KEY)
|
||||||
|
for (j in 0 until jsonArray.length()) {
|
||||||
|
val o = jsonArray.get(j) as JSONObject
|
||||||
|
periods.addLast(o.optLong(j.toString()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastChatsInfo.addLast(lastInfo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addTimePeriodToLastItem(id: Long, time: Long) {
|
||||||
|
val lastInfo = lastChatsInfo.find { it.chatId == id }
|
||||||
|
if (lastInfo == null) {
|
||||||
|
addItemToSuggested(id, time)
|
||||||
|
} else {
|
||||||
|
val index = lastChatsInfo.indexOf(lastInfo)
|
||||||
|
lastChatsInfo[index].periods = addTimeToPeriods(lastChatsInfo[index].periods, time)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addItemToSuggested(id: Long, time: Long) {
|
||||||
|
val newLastInfo = LastChatInfo().apply {
|
||||||
|
chatId = id
|
||||||
|
periods = LinkedList<Long>().apply {
|
||||||
|
addFirst(time)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (lastChatsInfo.size < 5) {
|
||||||
|
lastChatsInfo.addFirst(newLastInfo)
|
||||||
|
} else {
|
||||||
|
lastChatsInfo.removeLast()
|
||||||
|
lastChatsInfo.addFirst(newLastInfo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addTimeToPeriods(periods: LinkedList<Long>?, time: Long): LinkedList<Long> {
|
||||||
|
if (periods?.isNotEmpty() != null) {
|
||||||
|
return if (periods.size < 5) {
|
||||||
|
periods.addFirst(time)
|
||||||
|
periods
|
||||||
|
} else {
|
||||||
|
periods.removeLast()
|
||||||
|
periods.addFirst(time)
|
||||||
|
periods
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return LinkedList<Long>().apply { addFirst(time) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun calcLivePeriod(periods: LinkedList<Long>): Long {
|
||||||
|
val copy = periods.toLongArray()
|
||||||
|
copy.sort()
|
||||||
|
return if (copy.size % 2 == 0) {
|
||||||
|
(copy[copy.size / 2] + copy[copy.size / 2 - 1]) / 2
|
||||||
|
} else {
|
||||||
|
copy[copy.size / 2]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun getLiveNowChats() = app.telegramHelper.getMessagesByChatIds(locHistoryTime).keys
|
private fun getLiveNowChats() = app.telegramHelper.getMessagesByChatIds(locHistoryTime).keys
|
||||||
|
|
||||||
private fun updatePrefs() {
|
private fun updatePrefs() {
|
||||||
|
@ -1397,4 +1508,15 @@ class TelegramSettings(private val app: TelegramApplication) {
|
||||||
internal const val SENT_MESSAGES_KEY = "sentMessages"
|
internal const val SENT_MESSAGES_KEY = "sentMessages"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class LastChatInfo {
|
||||||
|
|
||||||
|
var chatId = -1L
|
||||||
|
var periods = LinkedList<Long>()
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
internal const val CHAT_ID_KEY = "chatId"
|
||||||
|
internal const val PERIODS_KEY = "periods"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -12,6 +12,8 @@ import android.support.v4.app.DialogFragment
|
||||||
import android.support.v4.app.Fragment
|
import android.support.v4.app.Fragment
|
||||||
import android.support.v4.app.FragmentManager
|
import android.support.v4.app.FragmentManager
|
||||||
import android.support.v4.app.FragmentPagerAdapter
|
import android.support.v4.app.FragmentPagerAdapter
|
||||||
|
import android.support.v4.view.PagerAdapter
|
||||||
|
import android.support.v4.view.ViewPager
|
||||||
import android.support.v7.app.AlertDialog
|
import android.support.v7.app.AlertDialog
|
||||||
import android.support.v7.app.AppCompatActivity
|
import android.support.v7.app.AppCompatActivity
|
||||||
import android.support.v7.widget.ListPopupWindow
|
import android.support.v7.widget.ListPopupWindow
|
||||||
|
@ -22,7 +24,6 @@ import net.osmand.PlatformUtil
|
||||||
import net.osmand.telegram.R
|
import net.osmand.telegram.R
|
||||||
import net.osmand.telegram.TelegramApplication
|
import net.osmand.telegram.TelegramApplication
|
||||||
import net.osmand.telegram.helpers.OsmandAidlHelper
|
import net.osmand.telegram.helpers.OsmandAidlHelper
|
||||||
import net.osmand.telegram.helpers.TelegramHelper
|
|
||||||
import net.osmand.telegram.helpers.TelegramHelper.*
|
import net.osmand.telegram.helpers.TelegramHelper.*
|
||||||
import net.osmand.telegram.ui.LoginDialogFragment.LoginDialogType
|
import net.osmand.telegram.ui.LoginDialogFragment.LoginDialogType
|
||||||
import net.osmand.telegram.ui.MyLocationTabFragment.ActionButtonsListener
|
import net.osmand.telegram.ui.MyLocationTabFragment.ActionButtonsListener
|
||||||
|
@ -43,7 +44,7 @@ private const val MY_LOCATION_TAB_POS = 0
|
||||||
private const val LIVE_NOW_TAB_POS = 1
|
private const val LIVE_NOW_TAB_POS = 1
|
||||||
private const val TIMELINE_TAB_POS = 2
|
private const val TIMELINE_TAB_POS = 2
|
||||||
|
|
||||||
class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListener, TelegramIncomingMessagesListener {
|
class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListener, TelegramIncomingMessagesListener, DataSetListener {
|
||||||
|
|
||||||
private val log = PlatformUtil.getLog(MainActivity::class.java)
|
private val log = PlatformUtil.getLog(MainActivity::class.java)
|
||||||
|
|
||||||
|
@ -66,6 +67,7 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene
|
||||||
private lateinit var buttonsBar: LinearLayout
|
private lateinit var buttonsBar: LinearLayout
|
||||||
private lateinit var bottomNav: BottomNavigationView
|
private lateinit var bottomNav: BottomNavigationView
|
||||||
private lateinit var coordinatorLayout: CoordinatorLayout
|
private lateinit var coordinatorLayout: CoordinatorLayout
|
||||||
|
private lateinit var viewPager: ViewPager
|
||||||
|
|
||||||
private var snackbarShown = false
|
private var snackbarShown = false
|
||||||
|
|
||||||
|
@ -81,7 +83,7 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene
|
||||||
|
|
||||||
paused = false
|
paused = false
|
||||||
|
|
||||||
val viewPager = findViewById<LockableViewPager>(R.id.view_pager).apply {
|
viewPager = findViewById<LockableViewPager>(R.id.view_pager).apply {
|
||||||
swipeLocked = true
|
swipeLocked = true
|
||||||
offscreenPageLimit = 3
|
offscreenPageLimit = 3
|
||||||
adapter = ViewPagerAdapter(supportFragmentManager)
|
adapter = ViewPagerAdapter(supportFragmentManager)
|
||||||
|
@ -484,6 +486,10 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onDataSetChanged() {
|
||||||
|
viewPager.adapter?.notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
|
||||||
private fun showOsmandMissingDialog() {
|
private fun showOsmandMissingDialog() {
|
||||||
OsmandMissingDialogFragment().show(supportFragmentManager, null)
|
OsmandMissingDialogFragment().show(supportFragmentManager, null)
|
||||||
}
|
}
|
||||||
|
@ -510,5 +516,13 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene
|
||||||
override fun getItem(position: Int) = fragments[position]
|
override fun getItem(position: Int) = fragments[position]
|
||||||
|
|
||||||
override fun getCount() = fragments.size
|
override fun getCount() = fragments.size
|
||||||
|
|
||||||
|
override fun getItemPosition(`object`: Any): Int {
|
||||||
|
return PagerAdapter.POSITION_NONE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface DataSetListener {
|
||||||
|
fun onDataSetChanged()
|
||||||
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@ package net.osmand.telegram.ui
|
||||||
import android.animation.*
|
import android.animation.*
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.graphics.ColorMatrix
|
||||||
|
import android.graphics.ColorMatrixColorFilter
|
||||||
import android.graphics.Typeface
|
import android.graphics.Typeface
|
||||||
import android.graphics.drawable.GradientDrawable
|
import android.graphics.drawable.GradientDrawable
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
@ -17,13 +19,12 @@ import android.text.SpannableString
|
||||||
import android.text.SpannableStringBuilder
|
import android.text.SpannableStringBuilder
|
||||||
import android.text.style.ForegroundColorSpan
|
import android.text.style.ForegroundColorSpan
|
||||||
import android.text.style.StyleSpan
|
import android.text.style.StyleSpan
|
||||||
|
import android.util.TypedValue
|
||||||
import android.view.*
|
import android.view.*
|
||||||
import android.view.animation.LinearInterpolator
|
import android.view.animation.LinearInterpolator
|
||||||
import android.widget.*
|
import android.widget.*
|
||||||
import net.osmand.telegram.ADDITIONAL_ACTIVE_TIME_VALUES_SEC
|
import net.osmand.PlatformUtil
|
||||||
import net.osmand.telegram.R
|
import net.osmand.telegram.*
|
||||||
import net.osmand.telegram.SHARE_TYPE_MAP
|
|
||||||
import net.osmand.telegram.TelegramApplication
|
|
||||||
import net.osmand.telegram.helpers.LocationMessages
|
import net.osmand.telegram.helpers.LocationMessages
|
||||||
import net.osmand.telegram.helpers.TelegramHelper
|
import net.osmand.telegram.helpers.TelegramHelper
|
||||||
import net.osmand.telegram.helpers.TelegramHelper.TelegramListener
|
import net.osmand.telegram.helpers.TelegramHelper.TelegramListener
|
||||||
|
@ -31,9 +32,13 @@ import net.osmand.telegram.helpers.TelegramUiHelper
|
||||||
import net.osmand.telegram.utils.AndroidUtils
|
import net.osmand.telegram.utils.AndroidUtils
|
||||||
import net.osmand.telegram.utils.OsmandFormatter
|
import net.osmand.telegram.utils.OsmandFormatter
|
||||||
import org.drinkless.td.libcore.telegram.TdApi
|
import org.drinkless.td.libcore.telegram.TdApi
|
||||||
|
import java.util.*
|
||||||
|
import kotlin.Comparator
|
||||||
|
import kotlin.collections.HashSet
|
||||||
|
|
||||||
private const val SELECTED_CHATS_KEY = "selected_chats"
|
private const val SELECTED_CHATS_KEY = "selected_chats"
|
||||||
private const val SELECTED_CHATS_USERS = "selected_users"
|
private const val SELECTED_CHATS_USERS = "selected_users"
|
||||||
|
private const val SUGGESTED = 2
|
||||||
private const val SHARE_LOCATION_CHAT = 1
|
private const val SHARE_LOCATION_CHAT = 1
|
||||||
private const val DEFAULT_CHAT = 0
|
private const val DEFAULT_CHAT = 0
|
||||||
|
|
||||||
|
@ -41,6 +46,8 @@ private const val ADAPTER_UPDATE_INTERVAL_MIL = 5 * 1000L // 5 sec
|
||||||
|
|
||||||
class MyLocationTabFragment : Fragment(), TelegramListener {
|
class MyLocationTabFragment : Fragment(), TelegramListener {
|
||||||
|
|
||||||
|
private val log = PlatformUtil.getLog(MyLocationTabFragment::class.java)
|
||||||
|
|
||||||
private var textMarginSmall: Int = 0
|
private var textMarginSmall: Int = 0
|
||||||
private var textMarginBig: Int = 0
|
private var textMarginBig: Int = 0
|
||||||
private var searchBoxHeight: Int = 0
|
private var searchBoxHeight: Int = 0
|
||||||
|
@ -85,6 +92,8 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
||||||
|
|
||||||
private var updateEnable: Boolean = false
|
private var updateEnable: Boolean = false
|
||||||
|
|
||||||
|
private lateinit var lastChatsInfo: LinkedList<TelegramSettings.LastChatInfo>
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
|
@ -234,6 +243,8 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lastChatsInfo = settings.lastChatsInfo
|
||||||
|
|
||||||
return mainView
|
return mainView
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,6 +279,7 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DisableSharingBottomSheet.SHARING_DISABLED_REQUEST_CODE -> {
|
DisableSharingBottomSheet.SHARING_DISABLED_REQUEST_CODE -> {
|
||||||
|
saveChatsToLastChatsInfo()
|
||||||
sharingMode = false
|
sharingMode = false
|
||||||
app.stopSharingLocation()
|
app.stopSharingLocation()
|
||||||
updateContent()
|
updateContent()
|
||||||
|
@ -487,7 +499,8 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateList() {
|
private fun updateList() {
|
||||||
val items: MutableList<TdApi.Object> = mutableListOf()
|
val lastItems = getLastShareItems()
|
||||||
|
val items: MutableList<Any> = mutableListOf()
|
||||||
val chats: MutableList<TdApi.Chat> = mutableListOf()
|
val chats: MutableList<TdApi.Chat> = mutableListOf()
|
||||||
val contacts = telegramHelper.getContacts()
|
val contacts = telegramHelper.getContacts()
|
||||||
val chatList = if (sharingMode) {
|
val chatList = if (sharingMode) {
|
||||||
|
@ -515,13 +528,42 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sharingMode && settings.hasAnyChatToShareLocation()) {
|
if (sharingMode && settings.hasAnyChatToShareLocation()) {
|
||||||
adapter.items = sortAdapterItems(items)
|
val filteredLastItems = lastItems.filter { !settings.isSharingLocationToChat(it.chat.id) }.toMutableList()
|
||||||
|
val sortedItems = sortAdapterItems(items as MutableList<TdApi.Object>)
|
||||||
|
sortedItems.add(SuggestedChats(filteredLastItems))
|
||||||
|
adapter.items = sortedItems
|
||||||
} else {
|
} else {
|
||||||
|
val filteredLastItems = lastItems.filter { !settings.isSharingLocationToChat(it.chat.id) }.toMutableList()
|
||||||
|
items.add(0, SuggestedChats(filteredLastItems))
|
||||||
adapter.items = items
|
adapter.items = items
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun sortAdapterItems(list: MutableList<TdApi.Object>): MutableList<TdApi.Object> {
|
private fun getLastShareItems(): MutableList<LastChat> {
|
||||||
|
val lastItems: MutableList<LastChat> = mutableListOf()
|
||||||
|
val chatListIds = telegramHelper.getChatListIds()
|
||||||
|
chatListIds.forEach { chatId ->
|
||||||
|
val chat = telegramHelper.getChat(chatId)
|
||||||
|
val lastInfo = lastChatsInfo.find { it.chatId == chatId }
|
||||||
|
if (chat != null && lastInfo != null) {
|
||||||
|
val index = lastChatsInfo.indexOf(lastInfo)
|
||||||
|
lastItems.add(LastChat(chat, settings.calcLivePeriod(lastChatsInfo[index].periods)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lastItems
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun saveChatsToLastChatsInfo() {
|
||||||
|
val chatListIds = settings.getShareLocationChats()
|
||||||
|
chatListIds.forEach { id ->
|
||||||
|
val shareInfo = settings.getChatsShareInfo()[id]
|
||||||
|
if (shareInfo != null) {
|
||||||
|
settings.addTimePeriodToLastItem(shareInfo.chatId, shareInfo.livePeriod)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun sortAdapterItems(list: MutableList<TdApi.Object>): MutableList<Any> {
|
||||||
list.sortWith(Comparator<TdApi.Object> { o1, o2 ->
|
list.sortWith(Comparator<TdApi.Object> { o1, o2 ->
|
||||||
val title1 = when (o1) {
|
val title1 = when (o1) {
|
||||||
is TdApi.Chat -> o1.title
|
is TdApi.Chat -> o1.title
|
||||||
|
@ -535,12 +577,12 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
||||||
}
|
}
|
||||||
title1.compareTo(title2)
|
title1.compareTo(title2)
|
||||||
})
|
})
|
||||||
return list
|
return list.toMutableList()
|
||||||
}
|
}
|
||||||
|
|
||||||
inner class MyLocationListAdapter :
|
inner class MyLocationListAdapter :
|
||||||
RecyclerView.Adapter<MyLocationListAdapter.BaseViewHolder>() {
|
RecyclerView.Adapter<MyLocationListAdapter.BaseViewHolder>() {
|
||||||
var items = mutableListOf<TdApi.Object>()
|
var items = mutableListOf<Any>()
|
||||||
set(value) {
|
set(value) {
|
||||||
field = value
|
field = value
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
|
@ -553,7 +595,9 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
||||||
is TdApi.User -> item.id.toLong()
|
is TdApi.User -> item.id.toLong()
|
||||||
else -> -1
|
else -> -1
|
||||||
}
|
}
|
||||||
return if (settings.isSharingLocationToChat(id) && sharingMode) {
|
return if (item is SuggestedChats) {
|
||||||
|
SUGGESTED
|
||||||
|
} else if (settings.isSharingLocationToChat(id) && sharingMode) {
|
||||||
SHARE_LOCATION_CHAT
|
SHARE_LOCATION_CHAT
|
||||||
} else {
|
} else {
|
||||||
DEFAULT_CHAT
|
DEFAULT_CHAT
|
||||||
|
@ -572,6 +616,11 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
||||||
.inflate(R.layout.user_list_item, parent, false)
|
.inflate(R.layout.user_list_item, parent, false)
|
||||||
ChatViewHolder(view)
|
ChatViewHolder(view)
|
||||||
}
|
}
|
||||||
|
SUGGESTED -> {
|
||||||
|
val view = LayoutInflater.from(parent.context)
|
||||||
|
.inflate(R.layout.suggested_list_item, parent, false)
|
||||||
|
SuggestedViewHolder(view)
|
||||||
|
}
|
||||||
else -> throw RuntimeException("Unsupported view type: $viewType")
|
else -> throw RuntimeException("Unsupported view type: $viewType")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -582,40 +631,18 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
||||||
val isChat = item is TdApi.Chat
|
val isChat = item is TdApi.Chat
|
||||||
val itemId = if (isChat) {
|
val itemId = if (isChat) {
|
||||||
(item as TdApi.Chat).id
|
(item as TdApi.Chat).id
|
||||||
|
} else if (item is TdApi.User) {
|
||||||
|
item.id.toLong()
|
||||||
} else {
|
} else {
|
||||||
(item as TdApi.User).id.toLong()
|
-1
|
||||||
}
|
}
|
||||||
|
|
||||||
val lastItem = position == itemCount - 1
|
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 live = (isChat && settings.isSharingLocationToChat(itemId))
|
||||||
val shareInfo = if (isChat) settings.getChatsShareInfo()[itemId] else null
|
val shareInfo = if (isChat) settings.getChatsShareInfo()[itemId] else null
|
||||||
|
|
||||||
val photoPath = when (item) {
|
setupPhoto(item, holder.icon, isChat)
|
||||||
is TdApi.Chat -> item.photo?.small?.local?.path
|
holder.title?.text = getTitleText(item)
|
||||||
is TdApi.User -> item.profilePhoto?.small?.local?.path
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
|
|
||||||
TelegramUiHelper.setupPhoto(app, holder.icon, photoPath, placeholderId, false)
|
|
||||||
|
|
||||||
val currentUserId = telegramHelper.getCurrentUserId()
|
|
||||||
val title = when (item) {
|
|
||||||
is TdApi.Chat -> {
|
|
||||||
if (telegramHelper.isPrivateChat(item) && (item.type as TdApi.ChatTypePrivate).userId == currentUserId) {
|
|
||||||
getString(R.string.saved_messages)
|
|
||||||
} else {
|
|
||||||
item.title
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is TdApi.User -> {
|
|
||||||
if (item.id == currentUserId) getString(R.string.saved_messages) else TelegramUiHelper.getUserName(item)
|
|
||||||
}
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
|
|
||||||
holder.title?.text = title
|
|
||||||
|
|
||||||
if (holder is ChatViewHolder) {
|
if (holder is ChatViewHolder) {
|
||||||
holder.description?.visibility = View.GONE
|
holder.description?.visibility = View.GONE
|
||||||
|
@ -669,8 +696,9 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
||||||
settings.shareLocationToChat(itemId, false)
|
settings.shareLocationToChat(itemId, false)
|
||||||
if (shareInfo != null) {
|
if (shareInfo != null) {
|
||||||
telegramHelper.stopSendingLiveLocationToChat(shareInfo)
|
telegramHelper.stopSendingLiveLocationToChat(shareInfo)
|
||||||
|
settings.addTimePeriodToLastItem(shareInfo.chatId,shareInfo.livePeriod)
|
||||||
}
|
}
|
||||||
removeItem(item)
|
removeItem(item as TdApi.Object)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -743,12 +771,113 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
||||||
text = description
|
text = description
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (holder is SuggestedViewHolder) {
|
||||||
|
holder.list.removeAllViews()
|
||||||
|
if ((item as SuggestedChats).list.isEmpty()) {
|
||||||
|
holder.container?.visibility = View.GONE
|
||||||
|
} else {
|
||||||
|
holder.container?.visibility = View.VISIBLE
|
||||||
|
val iterator = item.list.iterator()
|
||||||
|
iterator.forEach {
|
||||||
|
holder.list.addView(createLastChatView(it, iterator.hasNext()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
val tv = TypedValue()
|
||||||
|
if (!sharingMode) {
|
||||||
|
holder.dividerTop?.visibility = View.GONE
|
||||||
|
holder.dividerBottom?.visibility = View.VISIBLE
|
||||||
|
holder.header?.visibility = View.GONE
|
||||||
|
if (context?.theme?.resolveAttribute(R.attr.card_bg_color, tv, true) != null) {
|
||||||
|
holder.container?.setBackgroundColor(tv.data)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
holder.dividerTop?.visibility = View.VISIBLE
|
||||||
|
holder.dividerBottom?.visibility = View.GONE
|
||||||
|
holder.header?.visibility = View.VISIBLE
|
||||||
|
if (context?.theme?.resolveAttribute(R.attr.shared_chat_card_bg, tv, true) != null) {
|
||||||
|
holder.container?.setBackgroundResource(tv.resourceId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getTitleText(item: Any): String? {
|
||||||
|
val currentUserId = telegramHelper.getCurrentUserId()
|
||||||
|
return when (item) {
|
||||||
|
is LastChat -> {
|
||||||
|
if (telegramHelper.isPrivateChat(item.chat) && (item.chat.type as TdApi.ChatTypePrivate).userId == currentUserId) {
|
||||||
|
getString(R.string.saved_messages)
|
||||||
|
} else {
|
||||||
|
item.chat.title
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is TdApi.Chat -> {
|
||||||
|
if (telegramHelper.isPrivateChat(item) && (item.type as TdApi.ChatTypePrivate).userId == currentUserId) {
|
||||||
|
getString(R.string.saved_messages)
|
||||||
|
} else {
|
||||||
|
item.title
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is TdApi.User -> {
|
||||||
|
if (item.id == currentUserId) getString(R.string.saved_messages) else TelegramUiHelper.getUserName(item)
|
||||||
|
}
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupPhoto(item: Any, icon: ImageView?, isChat: Boolean) {
|
||||||
|
val photoPath = when (item) {
|
||||||
|
is LastChat -> item.chat.photo?.small?.local?.path
|
||||||
|
is TdApi.Chat -> item.photo?.small?.local?.path
|
||||||
|
is TdApi.User -> item.profilePhoto?.small?.local?.path
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
val placeholderId =
|
||||||
|
if (isChat && telegramHelper.isGroup(item as TdApi.Chat)) R.drawable.img_group_picture else R.drawable.img_user_picture
|
||||||
|
|
||||||
|
TelegramUiHelper.setupPhoto(app, icon, photoPath, placeholderId, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createLastChatView(lastChat: LastChat, hasNext: Boolean): View {
|
||||||
|
val view = layoutInflater.inflate(R.layout.last_share_list_item, null)
|
||||||
|
val time: TextView = view.findViewById(R.id.time)
|
||||||
|
val container: LinearLayout = view.findViewById(R.id.container)
|
||||||
|
val icon: ImageView = view.findViewById(R.id.icon)
|
||||||
|
val title: TextView = view.findViewById(R.id.title)
|
||||||
|
val divider: View = view.findViewById(R.id.divider)
|
||||||
|
|
||||||
|
if (sharingMode && hasNext) {
|
||||||
|
divider.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
|
||||||
|
container.setOnClickListener {
|
||||||
|
if (!AndroidUtils.isLocationPermissionAvailable(view!!.context)) {
|
||||||
|
AndroidUtils.requestLocationPermission(activity!!)
|
||||||
|
} else {
|
||||||
|
settings.shareLocationToChat(lastChat.chat.id, true, lastChat.time)
|
||||||
|
app.shareLocationHelper.startSharingLocation()
|
||||||
|
(activity as DataSetListener).onDataSetChanged()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
title.text = getTitleText(lastChat.chat)
|
||||||
|
setupPhoto(lastChat.chat, icon, true)
|
||||||
|
icon.colorFilter = ColorMatrixColorFilter(ColorMatrix().apply { setSaturation(0F) })
|
||||||
|
|
||||||
|
val sharingTime = SpannableStringBuilder("${getString(R.string.sharing_time)}: ")
|
||||||
|
val formattedTime = OsmandFormatter.getFormattedDuration(app, lastChat.time, false)
|
||||||
|
val start = sharingTime.length
|
||||||
|
sharingTime.append(formattedTime)
|
||||||
|
sharingTime.setSpan(StyleSpan(Typeface.BOLD), start, sharingTime.length, 0)
|
||||||
|
sharingTime.setSpan(ForegroundColorSpan(ContextCompat.getColor(app, R.color.ctrl_active_light)), start, sharingTime.length, 0)
|
||||||
|
time.text = sharingTime
|
||||||
|
return view
|
||||||
|
}
|
||||||
|
|
||||||
private fun removeItem(chat: TdApi.Object) {
|
private fun removeItem(chat: TdApi.Object) {
|
||||||
items.remove(chat)
|
items.remove(chat)
|
||||||
if (items.isEmpty()) {
|
val filtered = items.filterIsInstance<TdApi.Object>()
|
||||||
|
if (filtered.isEmpty()) {
|
||||||
sharingMode = false
|
sharingMode = false
|
||||||
updateContent()
|
updateContent()
|
||||||
shareLocationHelper.stopSharingLocation()
|
shareLocationHelper.stopSharingLocation()
|
||||||
|
@ -778,9 +907,21 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
||||||
val sharingExpiresLine: TextView? = view.findViewById(R.id.expires_line)
|
val sharingExpiresLine: TextView? = view.findViewById(R.id.expires_line)
|
||||||
val gpsPointsLine: TextView? = view.findViewById(R.id.gps_points_line)
|
val gpsPointsLine: TextView? = view.findViewById(R.id.gps_points_line)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inner class SuggestedViewHolder(val view: View) : BaseViewHolder(view) {
|
||||||
|
val list: LinearLayout = view.findViewById(R.id.last_items_list)
|
||||||
|
val container: LinearLayout? = view.findViewById(R.id.container)
|
||||||
|
val dividerBottom: View? = view.findViewById(R.id.divider_bottom)
|
||||||
|
val dividerTop: View? = view.findViewById(R.id.divider_top)
|
||||||
|
val header: TextView? = view.findViewById(R.id.header)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ActionButtonsListener {
|
interface ActionButtonsListener {
|
||||||
fun switchButtonsVisibility(visible: Boolean)
|
fun switchButtonsVisibility(visible: Boolean)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class LastChat internal constructor(val chat: TdApi.Chat, val time: Long)
|
||||||
|
|
||||||
|
class SuggestedChats internal constructor(val list: MutableList<LastChat>)
|
||||||
|
|
Loading…
Reference in a new issue