Telegram - added chats list
This commit is contained in:
parent
2a36e5ffb0
commit
27ccc38a08
19 changed files with 461 additions and 150 deletions
|
@ -120,6 +120,7 @@ dependencies {
|
|||
implementation 'com.android.support.constraint:constraint-layout:1.1.0'
|
||||
implementation 'com.android.support:support-annotations:27.1.1'
|
||||
implementation 'commons-logging:commons-logging-api:1.1'
|
||||
implementation 'com.android.support:recyclerview-v7:27.1.1'
|
||||
|
||||
testImplementation 'junit:junit:4.12'
|
||||
androidTestImplementation 'com.android.support.test:runner:1.0.2'
|
||||
|
|
|
@ -11,6 +11,8 @@ import android.view.WindowManager
|
|||
import android.view.inputmethod.EditorInfo
|
||||
import android.widget.Button
|
||||
import android.widget.EditText
|
||||
import net.osmand.telegram.utils.AndroidUtils
|
||||
import net.osmand.telegram.utils.PlatformUtil
|
||||
|
||||
|
||||
class LoginDialogFragment : DialogFragment() {
|
||||
|
|
|
@ -2,11 +2,12 @@ package net.osmand.telegram
|
|||
|
||||
import android.os.Bundle
|
||||
import android.support.v7.app.AppCompatActivity
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.support.v7.widget.*
|
||||
import android.view.*
|
||||
import android.widget.Toast
|
||||
import net.osmand.telegram.LoginDialogFragment.LoginDialogType
|
||||
import net.osmand.telegram.TelegramHelper.*
|
||||
import org.drinkless.td.libcore.telegram.TdApi
|
||||
|
||||
|
||||
class MainActivity : AppCompatActivity(), TelegramListener {
|
||||
|
@ -17,9 +18,13 @@ class MainActivity : AppCompatActivity(), TelegramListener {
|
|||
private const val PROGRESS_MENU_ID = 2
|
||||
}
|
||||
|
||||
private var authParamRequestHandler: AuthParamRequestHandler? = null
|
||||
private var telegramAuthorizationRequestHandler: TelegramAuthorizationRequestHandler? = null
|
||||
private var paused: Boolean = false
|
||||
|
||||
private lateinit var chatsView: RecyclerView
|
||||
private lateinit var chatViewAdapter: ChatsAdapter
|
||||
private lateinit var chatViewManager: RecyclerView.LayoutManager
|
||||
|
||||
private val app: TelegramApplication
|
||||
get() = application as TelegramApplication
|
||||
|
||||
|
@ -32,20 +37,30 @@ class MainActivity : AppCompatActivity(), TelegramListener {
|
|||
|
||||
paused = false
|
||||
|
||||
authParamRequestHandler = telegramHelper.setAuthParamRequestHandler(object : AuthParamRequestListener {
|
||||
override fun onRequestAuthParam(paramType: AuthParamType) {
|
||||
runOnUiThread {
|
||||
if (!paused) {
|
||||
showLoginDialog(paramType)
|
||||
}
|
||||
chatViewManager = LinearLayoutManager(this)
|
||||
chatViewAdapter = ChatsAdapter()
|
||||
|
||||
chatsView = findViewById<RecyclerView>(R.id.groups_view).apply {
|
||||
//setHasFixedSize(true)
|
||||
|
||||
// use a linear layout manager
|
||||
layoutManager = chatViewManager
|
||||
|
||||
// specify an viewAdapter (see also next example)
|
||||
adapter = chatViewAdapter
|
||||
|
||||
}
|
||||
|
||||
telegramAuthorizationRequestHandler = telegramHelper.setTelegramAuthorizationRequestHandler(object : TelegramAuthorizationRequestListener {
|
||||
override fun onRequestTelegramAuthenticationParameter(parameterType: TelegramAuthenticationParameterType) {
|
||||
runOnUi {
|
||||
showLoginDialog(parameterType)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onAuthRequestError(code: Int, message: String) {
|
||||
runOnUiThread {
|
||||
if (!paused) {
|
||||
Toast.makeText(this@MainActivity, "$code - $message", Toast.LENGTH_LONG).show()
|
||||
}
|
||||
override fun onTelegramAuthorizationRequestError(code: Int, message: String) {
|
||||
runOnUi {
|
||||
Toast.makeText(this@MainActivity, "$code - $message", Toast.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -66,24 +81,59 @@ class MainActivity : AppCompatActivity(), TelegramListener {
|
|||
paused = true
|
||||
}
|
||||
|
||||
override fun onTelegramStatusChanged(prevAutoState: AuthState, newAuthState: AuthState) {
|
||||
runOnUiThread {
|
||||
if (!paused) {
|
||||
val fm = supportFragmentManager
|
||||
when (newAuthState) {
|
||||
AuthState.READY,
|
||||
AuthState.CLOSED,
|
||||
AuthState.UNKNOWN -> LoginDialogFragment.dismiss(fm)
|
||||
else -> Unit
|
||||
override fun onTelegramStatusChanged(prevTelegramAuthorizationState: TelegramAuthorizationState,
|
||||
newTelegramAuthorizationState: TelegramAuthorizationState) {
|
||||
runOnUi {
|
||||
val fm = supportFragmentManager
|
||||
when (newTelegramAuthorizationState) {
|
||||
TelegramAuthorizationState.READY,
|
||||
TelegramAuthorizationState.CLOSED,
|
||||
TelegramAuthorizationState.UNKNOWN -> LoginDialogFragment.dismiss(fm)
|
||||
else -> Unit
|
||||
}
|
||||
invalidateOptionsMenu()
|
||||
updateTitle()
|
||||
|
||||
when (newTelegramAuthorizationState) {
|
||||
TelegramAuthorizationState.READY -> {
|
||||
updateChatsList()
|
||||
telegramHelper.requestChats()
|
||||
}
|
||||
invalidateOptionsMenu()
|
||||
updateTitle()
|
||||
TelegramAuthorizationState.CLOSED,
|
||||
TelegramAuthorizationState.UNKNOWN -> {
|
||||
chatViewAdapter.chats = emptyList()
|
||||
}
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onTelegramChatsRead() {
|
||||
runOnUi {
|
||||
updateChatsList()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onTelegramError(code: Int, message: String) {
|
||||
runOnUi {
|
||||
Toast.makeText(this@MainActivity, "$code - $message", Toast.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateChatsList() {
|
||||
val chatList = telegramHelper.getChatList()
|
||||
val chats: MutableList<TdApi.Chat> = mutableListOf()
|
||||
for (orderedChat in chatList) {
|
||||
val chat = telegramHelper.getChat(orderedChat.chatId)
|
||||
if (chat != null) {
|
||||
chats.add(chat)
|
||||
}
|
||||
}
|
||||
chatViewAdapter.chats = chats
|
||||
}
|
||||
|
||||
fun logoutTelegram(silent: Boolean = false) {
|
||||
if (telegramHelper.getAuthState() == AuthState.READY) {
|
||||
if (telegramHelper.getTelegramAuthorizationState() == TelegramAuthorizationState.READY) {
|
||||
telegramHelper.logout()
|
||||
} else {
|
||||
invalidateOptionsMenu()
|
||||
|
@ -98,6 +148,12 @@ class MainActivity : AppCompatActivity(), TelegramListener {
|
|||
telegramHelper.close()
|
||||
}
|
||||
|
||||
private fun runOnUi(action: (() -> Unit)) {
|
||||
if (!paused) {
|
||||
runOnUiThread(action)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
|
||||
return when (item?.itemId) {
|
||||
LOGIN_MENU_ID -> {
|
||||
|
@ -115,17 +171,17 @@ class MainActivity : AppCompatActivity(), TelegramListener {
|
|||
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
||||
if (menu != null) {
|
||||
menu.clear()
|
||||
when (telegramHelper.getAuthState()) {
|
||||
AuthState.UNKNOWN,
|
||||
AuthState.WAIT_PARAMETERS,
|
||||
AuthState.WAIT_PHONE_NUMBER,
|
||||
AuthState.WAIT_CODE,
|
||||
AuthState.WAIT_PASSWORD,
|
||||
AuthState.LOGGING_OUT,
|
||||
AuthState.CLOSING -> createProgressMenuItem(menu)
|
||||
AuthState.READY -> createMenuItem(menu, LOGOUT_MENU_ID, R.string.shared_string_logout,
|
||||
when (telegramHelper.getTelegramAuthorizationState()) {
|
||||
TelegramAuthorizationState.UNKNOWN,
|
||||
TelegramAuthorizationState.WAIT_PARAMETERS,
|
||||
TelegramAuthorizationState.WAIT_PHONE_NUMBER,
|
||||
TelegramAuthorizationState.WAIT_CODE,
|
||||
TelegramAuthorizationState.WAIT_PASSWORD,
|
||||
TelegramAuthorizationState.LOGGING_OUT,
|
||||
TelegramAuthorizationState.CLOSING -> createProgressMenuItem(menu)
|
||||
TelegramAuthorizationState.READY -> createMenuItem(menu, LOGOUT_MENU_ID, R.string.shared_string_logout,
|
||||
MenuItem.SHOW_AS_ACTION_WITH_TEXT or MenuItem.SHOW_AS_ACTION_ALWAYS)
|
||||
AuthState.CLOSED -> createMenuItem(menu, LOGIN_MENU_ID, R.string.shared_string_login,
|
||||
TelegramAuthorizationState.CLOSED -> createMenuItem(menu, LOGIN_MENU_ID, R.string.shared_string_login,
|
||||
MenuItem.SHOW_AS_ACTION_WITH_TEXT or MenuItem.SHOW_AS_ACTION_ALWAYS)
|
||||
}
|
||||
}
|
||||
|
@ -148,35 +204,35 @@ class MainActivity : AppCompatActivity(), TelegramListener {
|
|||
}
|
||||
|
||||
private fun updateTitle() {
|
||||
title = when (telegramHelper.getAuthState()) {
|
||||
title = when (telegramHelper.getTelegramAuthorizationState()) {
|
||||
|
||||
AuthState.UNKNOWN,
|
||||
AuthState.WAIT_PHONE_NUMBER,
|
||||
AuthState.WAIT_CODE,
|
||||
AuthState.WAIT_PASSWORD,
|
||||
AuthState.READY,
|
||||
AuthState.CLOSED -> getString(R.string.app_name)
|
||||
TelegramAuthorizationState.UNKNOWN,
|
||||
TelegramAuthorizationState.WAIT_PHONE_NUMBER,
|
||||
TelegramAuthorizationState.WAIT_CODE,
|
||||
TelegramAuthorizationState.WAIT_PASSWORD,
|
||||
TelegramAuthorizationState.READY,
|
||||
TelegramAuthorizationState.CLOSED -> getString(R.string.app_name)
|
||||
|
||||
AuthState.WAIT_PARAMETERS -> getString(R.string.initialization) + "..."
|
||||
AuthState.LOGGING_OUT -> getString(R.string.logging_out) + "..."
|
||||
AuthState.CLOSING -> getString(R.string.closing) + "..."
|
||||
TelegramAuthorizationState.WAIT_PARAMETERS -> getString(R.string.initialization) + "..."
|
||||
TelegramAuthorizationState.LOGGING_OUT -> getString(R.string.logging_out) + "..."
|
||||
TelegramAuthorizationState.CLOSING -> getString(R.string.closing) + "..."
|
||||
}
|
||||
}
|
||||
|
||||
private fun showLoginDialog(authParamType: AuthParamType) {
|
||||
when (authParamType) {
|
||||
AuthParamType.PHONE_NUMBER -> LoginDialogFragment.showDialog(supportFragmentManager, LoginDialogType.ENTER_PHONE_NUMBER)
|
||||
AuthParamType.CODE -> LoginDialogFragment.showDialog(supportFragmentManager, LoginDialogType.ENTER_CODE)
|
||||
AuthParamType.PASSWORD -> LoginDialogFragment.showDialog(supportFragmentManager, LoginDialogType.ENTER_PASSWORD)
|
||||
private fun showLoginDialog(telegramAuthenticationParameterType: TelegramAuthenticationParameterType) {
|
||||
when (telegramAuthenticationParameterType) {
|
||||
TelegramAuthenticationParameterType.PHONE_NUMBER -> LoginDialogFragment.showDialog(supportFragmentManager, LoginDialogType.ENTER_PHONE_NUMBER)
|
||||
TelegramAuthenticationParameterType.CODE -> LoginDialogFragment.showDialog(supportFragmentManager, LoginDialogType.ENTER_CODE)
|
||||
TelegramAuthenticationParameterType.PASSWORD -> LoginDialogFragment.showDialog(supportFragmentManager, LoginDialogType.ENTER_PASSWORD)
|
||||
}
|
||||
}
|
||||
|
||||
fun applyAuthParam(loginDialogFragment: LoginDialogFragment?, loginDialogType: LoginDialogType, text: String) {
|
||||
loginDialogFragment?.updateDialog(LoginDialogType.SHOW_PROGRESS)
|
||||
when (loginDialogType) {
|
||||
LoginDialogType.ENTER_PHONE_NUMBER -> authParamRequestHandler?.applyAuthParam(AuthParamType.PHONE_NUMBER, text)
|
||||
LoginDialogType.ENTER_CODE -> authParamRequestHandler?.applyAuthParam(AuthParamType.CODE, text)
|
||||
LoginDialogType.ENTER_PASSWORD -> authParamRequestHandler?.applyAuthParam(AuthParamType.PASSWORD, text)
|
||||
LoginDialogType.ENTER_PHONE_NUMBER -> telegramAuthorizationRequestHandler?.applyAuthenticationParameter(TelegramAuthenticationParameterType.PHONE_NUMBER, text)
|
||||
LoginDialogType.ENTER_CODE -> telegramAuthorizationRequestHandler?.applyAuthenticationParameter(TelegramAuthenticationParameterType.CODE, text)
|
||||
LoginDialogType.ENTER_PASSWORD -> telegramAuthorizationRequestHandler?.applyAuthenticationParameter(TelegramAuthenticationParameterType.PASSWORD, text)
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
|
@ -185,4 +241,35 @@ class MainActivity : AppCompatActivity(), TelegramListener {
|
|||
super.onDestroy()
|
||||
telegramHelper.close()
|
||||
}
|
||||
|
||||
inner class ChatsAdapter :
|
||||
RecyclerView.Adapter<ChatsAdapter.ViewHolder>() {
|
||||
|
||||
var chats: List<TdApi.Chat> = emptyList()
|
||||
set(value) {
|
||||
field = value
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
inner class ViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
|
||||
val icon: AppCompatImageView? = view.findViewById(R.id.icon)
|
||||
val groupName: AppCompatTextView? = view.findViewById(R.id.name)
|
||||
val shareLocationSwitch: SwitchCompat? = view.findViewById(R.id.share_location_switch)
|
||||
val showOnMapSwitch: SwitchCompat? = view.findViewById(R.id.show_on_map_switch)
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup,
|
||||
viewType: Int): ChatsAdapter.ViewHolder {
|
||||
val view = LayoutInflater.from(parent.context)
|
||||
.inflate(R.layout.chat_list_item, parent, false)
|
||||
|
||||
return ViewHolder(view)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
holder.groupName?.text = chats[position].title
|
||||
}
|
||||
|
||||
override fun getItemCount() = chats.size
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
package net.osmand.telegram
|
||||
|
||||
import android.text.TextUtils
|
||||
import net.osmand.telegram.TelegramHelper.AuthParamType.*
|
||||
import net.osmand.telegram.TelegramHelper.TelegramAuthenticationParameterType.*
|
||||
import net.osmand.telegram.utils.CancellableAsyncTask
|
||||
import net.osmand.telegram.utils.PlatformUtil
|
||||
import org.drinkless.td.libcore.telegram.Client
|
||||
import org.drinkless.td.libcore.telegram.Client.ResultHandler
|
||||
import org.drinkless.td.libcore.telegram.TdApi
|
||||
|
@ -10,12 +12,56 @@ import java.io.File
|
|||
import java.util.*
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
|
||||
class TelegramHelper private constructor() {
|
||||
|
||||
companion object {
|
||||
private val log = PlatformUtil.getLog(TelegramHelper::class.java)
|
||||
private const val CHATS_LIMIT = 100
|
||||
|
||||
private var helper: TelegramHelper? = null
|
||||
|
||||
private val users = ConcurrentHashMap<Int, TdApi.User>()
|
||||
private val basicGroups = ConcurrentHashMap<Int, TdApi.BasicGroup>()
|
||||
private val supergroups = ConcurrentHashMap<Int, TdApi.Supergroup>()
|
||||
private val secretChats = ConcurrentHashMap<Int, TdApi.SecretChat>()
|
||||
|
||||
private val chats = ConcurrentHashMap<Long, TdApi.Chat>()
|
||||
private val chatList = TreeSet<OrderedChat>()
|
||||
|
||||
private val usersFullInfo = ConcurrentHashMap<Int, TdApi.UserFullInfo>()
|
||||
private val basicGroupsFullInfo = ConcurrentHashMap<Int, TdApi.BasicGroupFullInfo>()
|
||||
private val supergroupsFullInfo = ConcurrentHashMap<Int, TdApi.SupergroupFullInfo>()
|
||||
|
||||
val instance: TelegramHelper
|
||||
get() {
|
||||
if (helper == null) {
|
||||
helper = TelegramHelper()
|
||||
}
|
||||
return helper!!
|
||||
}
|
||||
|
||||
private fun setChatOrder(chat: TdApi.Chat, order: Long) {
|
||||
synchronized(chatList) {
|
||||
if (chat.order != 0L) {
|
||||
chatList.remove(OrderedChat(chat.order, chat.id))
|
||||
}
|
||||
|
||||
chat.order = order
|
||||
|
||||
if (chat.order != 0L) {
|
||||
chatList.add(OrderedChat(chat.order, chat.id))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var appDir: String? = null
|
||||
private var libraryLoaded = false
|
||||
private var authParamRequestHandler: AuthParamRequestHandler? = null
|
||||
private var telegramAuthorizationRequestHandler: TelegramAuthorizationRequestHandler? = null
|
||||
|
||||
private var client: Client? = null
|
||||
private var haveFullChatList: Boolean = false
|
||||
|
||||
private var authorizationState: AuthorizationState? = null
|
||||
private var isHaveAuthorization = false
|
||||
|
@ -24,13 +70,23 @@ class TelegramHelper private constructor() {
|
|||
|
||||
var listener: TelegramListener? = null
|
||||
|
||||
enum class AuthParamType {
|
||||
fun getChatList(): TreeSet<OrderedChat> {
|
||||
synchronized(chatList) {
|
||||
return TreeSet<OrderedChat>(chatList)
|
||||
}
|
||||
}
|
||||
|
||||
fun getChat(id: Long): TdApi.Chat? {
|
||||
return chats[id]
|
||||
}
|
||||
|
||||
enum class TelegramAuthenticationParameterType {
|
||||
PHONE_NUMBER,
|
||||
CODE,
|
||||
PASSWORD
|
||||
}
|
||||
|
||||
enum class AuthState {
|
||||
enum class TelegramAuthorizationState {
|
||||
UNKNOWN,
|
||||
WAIT_PARAMETERS,
|
||||
WAIT_PHONE_NUMBER,
|
||||
|
@ -43,46 +99,51 @@ class TelegramHelper private constructor() {
|
|||
}
|
||||
|
||||
interface TelegramListener {
|
||||
fun onTelegramStatusChanged(prevAutoState: AuthState, newAuthState: AuthState)
|
||||
fun onTelegramStatusChanged(prevTelegramAuthorizationState: TelegramAuthorizationState,
|
||||
newTelegramAuthorizationState: TelegramAuthorizationState)
|
||||
|
||||
fun onTelegramChatsRead()
|
||||
fun onTelegramError(code: Int, message: String)
|
||||
}
|
||||
|
||||
interface AuthParamRequestListener {
|
||||
fun onRequestAuthParam(paramType: AuthParamType)
|
||||
fun onAuthRequestError(code: Int, message: String)
|
||||
interface TelegramAuthorizationRequestListener {
|
||||
fun onRequestTelegramAuthenticationParameter(parameterType: TelegramAuthenticationParameterType)
|
||||
fun onTelegramAuthorizationRequestError(code: Int, message: String)
|
||||
}
|
||||
|
||||
inner class AuthParamRequestHandler(val authParamRequestListener: AuthParamRequestListener) {
|
||||
inner class TelegramAuthorizationRequestHandler(val telegramAuthorizationRequestListener: TelegramAuthorizationRequestListener) {
|
||||
|
||||
fun applyAuthParam(paramType: AuthParamType, paramValue: String) {
|
||||
if (!TextUtils.isEmpty(paramValue)) {
|
||||
when (paramType) {
|
||||
PHONE_NUMBER -> client!!.send(TdApi.SetAuthenticationPhoneNumber(paramValue, false, false), AuthorizationRequestHandler())
|
||||
CODE -> client!!.send(TdApi.CheckAuthenticationCode(paramValue, "", ""), AuthorizationRequestHandler())
|
||||
PASSWORD -> client!!.send(TdApi.CheckAuthenticationPassword(paramValue), AuthorizationRequestHandler())
|
||||
fun applyAuthenticationParameter(parameterType: TelegramAuthenticationParameterType, parameterValue: String) {
|
||||
if (!TextUtils.isEmpty(parameterValue)) {
|
||||
when (parameterType) {
|
||||
PHONE_NUMBER -> client!!.send(TdApi.SetAuthenticationPhoneNumber(parameterValue, false, false), AuthorizationRequestHandler())
|
||||
CODE -> client!!.send(TdApi.CheckAuthenticationCode(parameterValue, "", ""), AuthorizationRequestHandler())
|
||||
PASSWORD -> client!!.send(TdApi.CheckAuthenticationPassword(parameterValue), AuthorizationRequestHandler())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getAuthState(): AuthState {
|
||||
val authorizationState = this.authorizationState ?: return AuthState.UNKNOWN
|
||||
fun getTelegramAuthorizationState(): TelegramAuthorizationState {
|
||||
val authorizationState = this.authorizationState
|
||||
?: return TelegramAuthorizationState.UNKNOWN
|
||||
return when (authorizationState.constructor) {
|
||||
TdApi.AuthorizationStateWaitTdlibParameters.CONSTRUCTOR -> AuthState.WAIT_PARAMETERS
|
||||
TdApi.AuthorizationStateWaitPhoneNumber.CONSTRUCTOR -> AuthState.WAIT_PHONE_NUMBER
|
||||
TdApi.AuthorizationStateWaitCode.CONSTRUCTOR -> AuthState.WAIT_CODE
|
||||
TdApi.AuthorizationStateWaitPassword.CONSTRUCTOR -> AuthState.WAIT_PASSWORD
|
||||
TdApi.AuthorizationStateReady.CONSTRUCTOR -> AuthState.READY
|
||||
TdApi.AuthorizationStateLoggingOut.CONSTRUCTOR -> AuthState.LOGGING_OUT
|
||||
TdApi.AuthorizationStateClosing.CONSTRUCTOR -> AuthState.CLOSING
|
||||
TdApi.AuthorizationStateClosed.CONSTRUCTOR -> AuthState.CLOSED
|
||||
else -> AuthState.UNKNOWN
|
||||
TdApi.AuthorizationStateWaitTdlibParameters.CONSTRUCTOR -> TelegramAuthorizationState.WAIT_PARAMETERS
|
||||
TdApi.AuthorizationStateWaitPhoneNumber.CONSTRUCTOR -> TelegramAuthorizationState.WAIT_PHONE_NUMBER
|
||||
TdApi.AuthorizationStateWaitCode.CONSTRUCTOR -> TelegramAuthorizationState.WAIT_CODE
|
||||
TdApi.AuthorizationStateWaitPassword.CONSTRUCTOR -> TelegramAuthorizationState.WAIT_PASSWORD
|
||||
TdApi.AuthorizationStateReady.CONSTRUCTOR -> TelegramAuthorizationState.READY
|
||||
TdApi.AuthorizationStateLoggingOut.CONSTRUCTOR -> TelegramAuthorizationState.LOGGING_OUT
|
||||
TdApi.AuthorizationStateClosing.CONSTRUCTOR -> TelegramAuthorizationState.CLOSING
|
||||
TdApi.AuthorizationStateClosed.CONSTRUCTOR -> TelegramAuthorizationState.CLOSED
|
||||
else -> TelegramAuthorizationState.UNKNOWN
|
||||
}
|
||||
}
|
||||
|
||||
fun setAuthParamRequestHandler(authParamRequestListener: AuthParamRequestListener): AuthParamRequestHandler {
|
||||
val authParamRequestHandler = AuthParamRequestHandler(authParamRequestListener)
|
||||
this.authParamRequestHandler = authParamRequestHandler
|
||||
return authParamRequestHandler
|
||||
fun setTelegramAuthorizationRequestHandler(telegramAuthorizationRequestListener: TelegramAuthorizationRequestListener): TelegramAuthorizationRequestHandler {
|
||||
val handler = TelegramAuthorizationRequestHandler(telegramAuthorizationRequestListener)
|
||||
this.telegramAuthorizationRequestHandler = handler
|
||||
return handler
|
||||
}
|
||||
|
||||
init {
|
||||
|
@ -108,6 +169,42 @@ class TelegramHelper private constructor() {
|
|||
}
|
||||
}
|
||||
|
||||
fun requestChats() {
|
||||
synchronized(chatList) {
|
||||
if (!haveFullChatList && CHATS_LIMIT > chatList.size) {
|
||||
// have enough chats in the chat list or chat list is too small
|
||||
var offsetOrder = java.lang.Long.MAX_VALUE
|
||||
var offsetChatId: Long = 0
|
||||
if (!chatList.isEmpty()) {
|
||||
val last = chatList.last()
|
||||
offsetOrder = last.order
|
||||
offsetChatId = last.chatId
|
||||
}
|
||||
client?.send(TdApi.GetChats(offsetOrder, offsetChatId, CHATS_LIMIT - chatList.size), { obj ->
|
||||
when (obj.constructor) {
|
||||
TdApi.Error.CONSTRUCTOR -> {
|
||||
val error = obj as TdApi.Error
|
||||
listener?.onTelegramError(error.code, error.message)
|
||||
}
|
||||
TdApi.Chats.CONSTRUCTOR -> {
|
||||
val chatIds = (obj as TdApi.Chats).chatIds
|
||||
if (chatIds.isEmpty()) {
|
||||
synchronized(chatList) {
|
||||
haveFullChatList = true
|
||||
}
|
||||
}
|
||||
// chats had already been received through updates, let's retry request
|
||||
requestChats()
|
||||
}
|
||||
else -> listener?.onTelegramError(-1, "Receive wrong response from TDLib: $obj")
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
listener?.onTelegramChatsRead()
|
||||
}
|
||||
|
||||
fun logout(): Boolean {
|
||||
return if (libraryLoaded) {
|
||||
isHaveAuthorization = false
|
||||
|
@ -129,7 +226,7 @@ class TelegramHelper private constructor() {
|
|||
}
|
||||
|
||||
private fun onAuthorizationStateUpdated(authorizationState: AuthorizationState?) {
|
||||
val prevAuthState = getAuthState()
|
||||
val prevAuthState = getTelegramAuthorizationState()
|
||||
if (authorizationState != null) {
|
||||
this.authorizationState = authorizationState
|
||||
}
|
||||
|
@ -156,15 +253,15 @@ class TelegramHelper private constructor() {
|
|||
}
|
||||
TdApi.AuthorizationStateWaitPhoneNumber.CONSTRUCTOR -> {
|
||||
log.info("Request phone number")
|
||||
authParamRequestHandler?.authParamRequestListener?.onRequestAuthParam(PHONE_NUMBER)
|
||||
telegramAuthorizationRequestHandler?.telegramAuthorizationRequestListener?.onRequestTelegramAuthenticationParameter(PHONE_NUMBER)
|
||||
}
|
||||
TdApi.AuthorizationStateWaitCode.CONSTRUCTOR -> {
|
||||
log.info("Request code")
|
||||
authParamRequestHandler?.authParamRequestListener?.onRequestAuthParam(CODE)
|
||||
telegramAuthorizationRequestHandler?.telegramAuthorizationRequestListener?.onRequestTelegramAuthenticationParameter(CODE)
|
||||
}
|
||||
TdApi.AuthorizationStateWaitPassword.CONSTRUCTOR -> {
|
||||
log.info("Request password")
|
||||
authParamRequestHandler?.authParamRequestListener?.onRequestAuthParam(PASSWORD)
|
||||
telegramAuthorizationRequestHandler?.telegramAuthorizationRequestListener?.onRequestTelegramAuthenticationParameter(PASSWORD)
|
||||
}
|
||||
TdApi.AuthorizationStateReady.CONSTRUCTOR -> {
|
||||
isHaveAuthorization = true
|
||||
|
@ -183,11 +280,11 @@ class TelegramHelper private constructor() {
|
|||
}
|
||||
else -> log.error("Unsupported authorization state: " + this.authorizationState!!)
|
||||
}
|
||||
val newAuthState = getAuthState()
|
||||
val newAuthState = getTelegramAuthorizationState()
|
||||
listener?.onTelegramStatusChanged(prevAuthState, newAuthState)
|
||||
}
|
||||
|
||||
private class OrderedChat internal constructor(internal val order: Long, internal val chatId: Long) : Comparable<OrderedChat> {
|
||||
class OrderedChat internal constructor(internal val order: Long, internal val chatId: Long) : Comparable<OrderedChat> {
|
||||
|
||||
override fun compareTo(other: OrderedChat): Int {
|
||||
if (this.order != other.order) {
|
||||
|
@ -257,6 +354,9 @@ class TelegramHelper private constructor() {
|
|||
chat.order = 0
|
||||
setChatOrder(chat, order)
|
||||
}
|
||||
CancellableAsyncTask.run("onTelegramChatsRead", 100, {
|
||||
listener?.onTelegramChatsRead()
|
||||
})
|
||||
}
|
||||
TdApi.UpdateChatTitle.CONSTRUCTOR -> {
|
||||
val updateChat = obj as TdApi.UpdateChatTitle
|
||||
|
@ -371,7 +471,7 @@ class TelegramHelper private constructor() {
|
|||
TdApi.Error.CONSTRUCTOR -> {
|
||||
log.error("Receive an error: $obj")
|
||||
val errorObj = obj as TdApi.Error
|
||||
authParamRequestHandler?.authParamRequestListener?.onAuthRequestError(errorObj.code, errorObj.message)
|
||||
telegramAuthorizationRequestHandler?.telegramAuthorizationRequestListener?.onTelegramAuthorizationRequestError(errorObj.code, errorObj.message)
|
||||
onAuthorizationStateUpdated(null) // repeat last action
|
||||
}
|
||||
TdApi.Ok.CONSTRUCTOR -> {
|
||||
|
@ -380,44 +480,4 @@ class TelegramHelper private constructor() {
|
|||
}// result is already received through UpdateAuthorizationState, nothing to do
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val log = PlatformUtil.getLog(TelegramHelper::class.java)
|
||||
|
||||
private var helper: TelegramHelper? = null
|
||||
|
||||
private val users = ConcurrentHashMap<Int, TdApi.User>()
|
||||
private val basicGroups = ConcurrentHashMap<Int, TdApi.BasicGroup>()
|
||||
private val supergroups = ConcurrentHashMap<Int, TdApi.Supergroup>()
|
||||
private val secretChats = ConcurrentHashMap<Int, TdApi.SecretChat>()
|
||||
|
||||
private val chats = ConcurrentHashMap<Long, TdApi.Chat>()
|
||||
private val chatList = TreeSet<OrderedChat>()
|
||||
|
||||
private val usersFullInfo = ConcurrentHashMap<Int, TdApi.UserFullInfo>()
|
||||
private val basicGroupsFullInfo = ConcurrentHashMap<Int, TdApi.BasicGroupFullInfo>()
|
||||
private val supergroupsFullInfo = ConcurrentHashMap<Int, TdApi.SupergroupFullInfo>()
|
||||
|
||||
val instance: TelegramHelper
|
||||
get() {
|
||||
if (helper == null) {
|
||||
helper = TelegramHelper()
|
||||
}
|
||||
return helper!!
|
||||
}
|
||||
|
||||
private fun setChatOrder(chat: TdApi.Chat, order: Long) {
|
||||
synchronized(chatList) {
|
||||
if (chat.order != 0L) {
|
||||
chatList.remove(OrderedChat(chat.order, chat.id))
|
||||
}
|
||||
|
||||
chat.order = order
|
||||
|
||||
if (chat.order != 0L) {
|
||||
chatList.add(OrderedChat(chat.order, chat.id))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package net.osmand.telegram
|
||||
package net.osmand.telegram.utils
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
|
@ -0,0 +1,76 @@
|
|||
package net.osmand.telegram.utils
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import java.util.concurrent.ExecutorService
|
||||
import java.util.concurrent.Executors
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
|
||||
class CancellableAsyncTask(val taskId: String, val executeTimeout: Long = 0) {
|
||||
|
||||
companion object {
|
||||
private const val SLEEP_TIME = 50L
|
||||
private val requestNumbersMap = ConcurrentHashMap<String, AtomicInteger>()
|
||||
private val singleThreadExecutorsMap = ConcurrentHashMap<String, ExecutorService>()
|
||||
|
||||
fun run(taskId: String, executeTimeout: Long = 0, action: (() -> Unit)) {
|
||||
CancellableAsyncTask(taskId, executeTimeout).run(action)
|
||||
}
|
||||
|
||||
fun clearResources(taskId: String) {
|
||||
requestNumbersMap.remove(taskId)
|
||||
singleThreadExecutorsMap.remove(taskId)
|
||||
}
|
||||
}
|
||||
|
||||
private val singleThreadExecutor: ExecutorService
|
||||
private var requestNumber: AtomicInteger
|
||||
|
||||
var isCancelled: Boolean = false
|
||||
|
||||
init {
|
||||
val requestNumber = requestNumbersMap[taskId]
|
||||
if (requestNumber == null) {
|
||||
this.requestNumber = AtomicInteger()
|
||||
requestNumbersMap[taskId] = this.requestNumber
|
||||
} else {
|
||||
this.requestNumber = requestNumber
|
||||
}
|
||||
|
||||
val singleThreadExecutor = singleThreadExecutorsMap[taskId]
|
||||
if (singleThreadExecutor == null) {
|
||||
this.singleThreadExecutor = Executors.newSingleThreadExecutor()
|
||||
singleThreadExecutorsMap[taskId] = this.singleThreadExecutor
|
||||
} else {
|
||||
this.singleThreadExecutor = singleThreadExecutor
|
||||
}
|
||||
}
|
||||
|
||||
fun run(action: (() -> Unit)) {
|
||||
val req = requestNumber.incrementAndGet()
|
||||
|
||||
singleThreadExecutor.submit(object : Runnable {
|
||||
|
||||
private val isCancelled: Boolean
|
||||
get() = requestNumber.get() != req || this@CancellableAsyncTask.isCancelled
|
||||
|
||||
override fun run() {
|
||||
try {
|
||||
if (executeTimeout > 0) {
|
||||
val startTime = System.currentTimeMillis()
|
||||
while (System.currentTimeMillis() - startTime <= executeTimeout) {
|
||||
if (isCancelled) {
|
||||
return
|
||||
}
|
||||
Thread.sleep(SLEEP_TIME)
|
||||
}
|
||||
}
|
||||
if (!isCancelled) {
|
||||
action.invoke()
|
||||
}
|
||||
} catch (e: InterruptedException) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package net.osmand.telegram;
|
||||
package net.osmand.telegram.utils;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
BIN
OsmAnd-telegram/src/main/res/drawable-hdpi/ic_group.png
Normal file
BIN
OsmAnd-telegram/src/main/res/drawable-hdpi/ic_group.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
BIN
OsmAnd-telegram/src/main/res/drawable-mdpi/ic_group.png
Normal file
BIN
OsmAnd-telegram/src/main/res/drawable-mdpi/ic_group.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
BIN
OsmAnd-telegram/src/main/res/drawable-xhdpi/ic_group.png
Normal file
BIN
OsmAnd-telegram/src/main/res/drawable-xhdpi/ic_group.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
BIN
OsmAnd-telegram/src/main/res/drawable-xxhdpi/ic_group.png
Normal file
BIN
OsmAnd-telegram/src/main/res/drawable-xxhdpi/ic_group.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
|
@ -3,11 +3,11 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingLeft="16dp">
|
||||
android:paddingRight="@dimen/content_padding_standard"
|
||||
android:paddingLeft="@dimen/content_padding_standard">
|
||||
|
||||
<ProgressBar
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp" />
|
||||
android:layout_width="@dimen/progress_bar_size_small"
|
||||
android:layout_height="@dimen/progress_bar_size_small" />
|
||||
|
||||
</LinearLayout>
|
|
@ -1,16 +1,14 @@
|
|||
<?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="match_parent"
|
||||
tools:context=".MainActivity">
|
||||
|
||||
<TextView
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/groups_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:text="Hello World!" />
|
||||
android:layout_height="match_parent"
|
||||
android:scrollbars="vertical" />
|
||||
|
||||
</LinearLayout>
|
61
OsmAnd-telegram/src/main/res/layout/chat_list_item.xml
Normal file
61
OsmAnd-telegram/src/main/res/layout/chat_list_item.xml
Normal file
|
@ -0,0 +1,61 @@
|
|||
<?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:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:descendantFocusability="blocksDescendants"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/bg_color"
|
||||
android:minHeight="@dimen/list_item_height_min"
|
||||
android:orientation="horizontal"
|
||||
android:paddingBottom="@dimen/content_padding_half"
|
||||
android:paddingLeft="@dimen/content_padding_standard"
|
||||
android:paddingStart="@dimen/content_padding_standard"
|
||||
android:paddingTop="@dimen/content_padding_half">
|
||||
|
||||
<android.support.v7.widget.AppCompatImageView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:scaleType="centerInside"
|
||||
android:src="@drawable/ic_group"
|
||||
android:tint="?attr/icon_color"
|
||||
android:visibility="visible" />
|
||||
|
||||
<android.support.v7.widget.AppCompatTextView
|
||||
android:id="@+id/name"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginLeft="@dimen/content_padding_half"
|
||||
android:layout_marginStart="@dimen/content_padding_half"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center_vertical"
|
||||
tools:text="Group name" />
|
||||
|
||||
<android.support.v7.widget.SwitchCompat
|
||||
android:id="@+id/share_location_switch"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginEnd="@dimen/content_padding_half"
|
||||
android:layout_marginLeft="@dimen/content_padding_standard"
|
||||
android:layout_marginRight="@dimen/content_padding_half"
|
||||
android:layout_marginStart="@dimen/content_padding_standard"
|
||||
android:focusableInTouchMode="true" />
|
||||
|
||||
<android.support.v7.widget.SwitchCompat
|
||||
android:id="@+id/show_on_map_switch"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginEnd="@dimen/content_padding_standard"
|
||||
android:layout_marginLeft="@dimen/content_padding_half"
|
||||
android:layout_marginRight="@dimen/content_padding_standard"
|
||||
android:layout_marginStart="@dimen/content_padding_half"
|
||||
android:focusableInTouchMode="true" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
|
@ -4,10 +4,10 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fillViewport="true"
|
||||
android:paddingBottom="24dp"
|
||||
android:paddingLeft="48dp"
|
||||
android:paddingRight="48dp"
|
||||
android:paddingTop="24dp">
|
||||
android:paddingBottom="@dimen/dialog_padding_vertical"
|
||||
android:paddingLeft="@dimen/dialog_padding_horizontal"
|
||||
android:paddingRight="@dimen/dialog_padding_horizontal"
|
||||
android:paddingTop="@dimen/dialog_padding_vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
@ -20,7 +20,7 @@
|
|||
android:layout_weight="0.2"
|
||||
android:gravity="center"
|
||||
android:text="@string/login_to_telegram"
|
||||
android:textSize="22sp"
|
||||
android:textSize="@dimen/dialog_title_text_size"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<LinearLayout
|
||||
|
@ -106,8 +106,8 @@
|
|||
android:visibility="visible">
|
||||
|
||||
<ProgressBar
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp" />
|
||||
android:layout_width="@dimen/progress_bar_size_small"
|
||||
android:layout_height="@dimen/progress_bar_size_small" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
|
7
OsmAnd-telegram/src/main/res/values/attrs.xml
Normal file
7
OsmAnd-telegram/src/main/res/values/attrs.xml
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<declare-styleable name="AppTheme">
|
||||
<attr name="bg_color" format="reference" />
|
||||
<attr name="icon_color" format="reference" />
|
||||
</declare-styleable>
|
||||
</resources>
|
|
@ -3,4 +3,10 @@
|
|||
<color name="colorPrimary">#3F51B5</color>
|
||||
<color name="colorPrimaryDark">#303F9F</color>
|
||||
<color name="colorAccent">#FF4081</color>
|
||||
|
||||
<color name="bg_color_light">#fff</color>
|
||||
<color name="bg_color_dark">#333b40</color>
|
||||
<color name="icon_color_light">#ccc</color>
|
||||
<color name="icon_color_dark">#ff4f4f4f</color>
|
||||
|
||||
</resources>
|
||||
|
|
10
OsmAnd-telegram/src/main/res/values/dimens.xml
Normal file
10
OsmAnd-telegram/src/main/res/values/dimens.xml
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<dimen name="content_padding_half">8dp</dimen>
|
||||
<dimen name="content_padding_standard">16dp</dimen>
|
||||
<dimen name="progress_bar_size_small">32dp</dimen>
|
||||
<dimen name="dialog_title_text_size">22sp</dimen>
|
||||
<dimen name="dialog_padding_vertical">24dp</dimen>
|
||||
<dimen name="dialog_padding_horizontal">48dp</dimen>
|
||||
<dimen name="list_item_height_min">48dp</dimen>
|
||||
</resources>
|
|
@ -6,6 +6,9 @@
|
|||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="colorAccent">@color/colorAccent</item>
|
||||
|
||||
<item name="bg_color">@color/bg_color_light</item>
|
||||
<item name="icon_color">@color/icon_color_light</item>
|
||||
</style>
|
||||
|
||||
<style name="AppTheme.NoActionbar">
|
||||
|
|
Loading…
Reference in a new issue