test conversations loading

This commit is contained in:
2021-09-10 19:59:45 +03:00
parent 9a9bde97cb
commit 9e8d9247dc
36 changed files with 373 additions and 175 deletions
@@ -0,0 +1,9 @@
package com.meloda.fast.api
import com.meloda.fast.api.loader.UsersLoader
object LoadManager {
val users = UsersLoader()
}
@@ -24,9 +24,9 @@ object VKUtil {
}
fun sortMessagesByDate(
values: ArrayList<VKMessage>,
values: ArrayList<oldVKMessage>,
firstOnTop: Boolean
): ArrayList<VKMessage> {
): ArrayList<oldVKMessage> {
values.sortWith { m1, m2 ->
val d1 = m1.date
val d2 = m2.date
@@ -42,9 +42,9 @@ object VKUtil {
}
fun sortConversationsByDate(
values: ArrayList<VKConversation>,
values: ArrayList<oldVKConversation>,
firstOnTop: Boolean
): ArrayList<VKConversation> {
): ArrayList<oldVKConversation> {
values.sortWith { c1, c2 ->
val d1 = c1.lastMessage.date
val d2 = c2.lastMessage.date
@@ -119,8 +119,8 @@ object VKUtil {
fun getTitle(
conversation: VKConversation,
peerUser: VKUser?,
conversation: oldVKConversation,
peerUser: oldVKUser?,
peerGroup: VKGroup?
): String {
return when {
@@ -137,8 +137,8 @@ object VKUtil {
}
fun getMessageTitle(
message: VKMessage,
fromUser: VKUser?,
message: oldVKMessage,
fromUser: oldVKUser?,
fromGroup: VKGroup?
): String {
return when {
@@ -155,8 +155,8 @@ object VKUtil {
}
fun getAvatar(
conversation: VKConversation,
peerUser: VKUser?,
conversation: oldVKConversation,
peerUser: oldVKUser?,
peerGroup: VKGroup?
): String {
return when {
@@ -177,8 +177,8 @@ object VKUtil {
}
fun getUserAvatar(
message: VKMessage,
fromUser: VKUser?,
message: oldVKMessage,
fromUser: oldVKUser?,
fromGroup: VKGroup?
): String {
return when {
@@ -194,7 +194,7 @@ object VKUtil {
}
}
fun getUserPhoto(user: VKUser): String {
fun getUserPhoto(user: oldVKUser): String {
if (user.photo200.isEmpty()) {
if (user.photo100.isEmpty()) {
if (user.photo50.isEmpty()) {
@@ -227,26 +227,26 @@ object VKUtil {
}
fun parseConversations(array: JSONArray): ArrayList<VKConversation> {
val conversations = arrayListOf<VKConversation>()
fun parseConversations(array: JSONArray): ArrayList<oldVKConversation> {
val conversations = arrayListOf<oldVKConversation>()
for (i in 0 until array.length()) {
conversations.add(VKConversation(array.optJSONObject(i)))
conversations.add(oldVKConversation(array.optJSONObject(i)))
}
return conversations
}
fun parseMessages(array: JSONArray): ArrayList<VKMessage> {
val messages = arrayListOf<VKMessage>()
fun parseMessages(array: JSONArray): ArrayList<oldVKMessage> {
val messages = arrayListOf<oldVKMessage>()
for (i in 0 until array.length()) {
messages.add(VKMessage(array.optJSONObject(i)))
messages.add(oldVKMessage(array.optJSONObject(i)))
}
return messages
}
fun isMessageHasFlag(mask: Int, flagName: String): Boolean {
val o: Any? = VKMessage.flags[flagName]
val o: Any? = oldVKMessage.flags[flagName]
return if (o != null) { //has flag
val flag = o as Int
flag and mask > 0
@@ -257,8 +257,8 @@ object VKUtil {
//fromUser and fromGroup are null
@Deprecated("need to rewrite")
@WorkerThread
fun parseLongPollMessage(array: JSONArray): VKMessage {
val message = VKMessage()
fun parseLongPollMessage(array: JSONArray): oldVKMessage {
val message = oldVKMessage()
val id = array.optInt(1)
val flags = array.optInt(2)
@@ -302,7 +302,7 @@ object VKUtil {
action.conversationMessageId = it.optInt("source_chat_local_id")
it.optJSONObject("source_message")?.let { message ->
action.message = VKMessage(message)
action.message = oldVKMessage(message)
}
}
VKMessageAction.Type.UNPIN_MESSAGE -> {
@@ -0,0 +1,8 @@
package com.meloda.fast.api.loader
abstract class Loader<T> {
abstract suspend fun load(params: MutableMap<String, Any>): List<T>
abstract suspend fun loadSingle(params: MutableMap<String, Any>): T
}
@@ -0,0 +1,41 @@
package com.meloda.fast.api.loader
import com.meloda.fast.api.model.VkUser
import com.meloda.fast.api.network.repo.UsersRepo
import com.meloda.fast.api.network.request.UsersGetRequest
import javax.inject.Inject
class UsersLoader : Loader<VkUser>() {
@Inject
lateinit var repo: UsersRepo
suspend fun load(
usersIds: List<Int>,
fields: String = ""
) = load(
mutableMapOf(
"usersIds" to usersIds.joinToString { it.toString() },
"fields" to fields
)
)
override suspend fun load(params: MutableMap<String, Any>): List<VkUser> {
val usersIds: String = params["usersIds"] as String
val fields: String = params["fields"] as String
val users = repo.getById(
UsersGetRequest(
usersIds = usersIds.split(",").map { it.toInt() },
fields = fields
)
)
return emptyList()
}
override suspend fun loadSingle(params: MutableMap<String, Any>): VkUser {
return load(params)[0]
}
}
@@ -6,9 +6,9 @@ class VKLongPollHistory : VKModel() {
override val attachmentType = VKAttachments.Type.NONE
private val lpMessages: ArrayList<VKMessage>? = null
private val messages: ArrayList<VKMessage>? = null
private val profiles: ArrayList<VKUser>? = null
private val lpMessages: ArrayList<oldVKMessage>? = null
private val messages: ArrayList<oldVKMessage>? = null
private val profiles: ArrayList<oldVKUser>? = null
private val groups: ArrayList<VKGroup>? = null //TODO: использовать
}
@@ -12,7 +12,7 @@ class VKMessageAction() : VKModel() {
var type: Type = Type.NONE
var memberId = 0
var message: VKMessage? = null
var message: oldVKMessage? = null
var conversationMessageId: Int = 0
var text: String = ""
var oldText: String = ""
@@ -0,0 +1,7 @@
package com.meloda.fast.api.model
data class VkConversation(
val id: Int,
val title: String?,
val lastMessage: VkMessage
)
@@ -0,0 +1,10 @@
package com.meloda.fast.api.model
data class VkMessage(
val id: Int,
val text: String?,
val isOut: Boolean,
val peerId: Int,
val fromId: Int,
val date: Int
)
@@ -0,0 +1,7 @@
package com.meloda.fast.api.model
data class VkUser(
val id: Int,
val firstName: String,
val lastName: String
)
@@ -1,11 +1,11 @@
package com.meloda.fast.api.model
package com.meloda.fast.api.model.base
import android.os.Parcelable
import com.google.gson.annotations.SerializedName
import kotlinx.parcelize.Parcelize
@Parcelize
data class BaseVKConversation(
data class BaseVkConversation(
val peer: Peer,
@SerializedName("last_message_id")
val lastMessageId: Int,
@@ -29,7 +29,7 @@ data class BaseVKConversation(
@SerializedName("can_receive_money")
val canReceiveMoney: Boolean,
@SerializedName("chat_settings")
val chatSettings: ChatSettings
val chatSettings: ChatSettings?
) : Parcelable {
@Parcelize
@@ -1,4 +1,4 @@
package com.meloda.fast.api.model
package com.meloda.fast.api.model.base
import android.os.Parcelable
import com.google.gson.annotations.SerializedName
@@ -6,7 +6,7 @@ import kotlinx.parcelize.Parcelize
import kotlinx.parcelize.RawValue
@Parcelize
data class BaseVKMessage(
data class BaseVkMessage(
val date: Int,
@SerializedName("from_id")
val fromId: Int,
@@ -18,7 +18,7 @@ data class BaseVKMessage(
@SerializedName("conversation_message_id")
val conversationMessageId: Int,
@SerializedName("fwd_messages")
val fwdMessages: List<BaseVKMessage> = listOf(),
val fwdMessages: List<BaseVkMessage> = listOf(),
val important: Boolean,
@SerializedName("random_id")
val randomId: Int,
@@ -0,0 +1,49 @@
package com.meloda.fast.api.model.base
import android.os.Parcelable
import com.google.gson.annotations.SerializedName
import kotlinx.parcelize.Parcelize
@Parcelize
data class BaseVkUser(
val id: Int,
@SerializedName("first_name")
val firstName: String,
@SerializedName("last_name")
val lastName: String,
@SerializedName("can_access_closed")
val canAccessClosed: Boolean,
@SerializedName("is_closed")
val isClosed: Boolean,
@SerializedName("can_invite_to_chats")
val canInviteToChats: Boolean,
val sex: Int?,
@SerializedName("photo_50")
val photo50: String?,
@SerializedName("photo_100")
val photo100: String?,
@SerializedName("photo_200")
val photo200: String?,
val online: Int?,
@SerializedName("online_info")
val onlineInfo: OnlineInfo?,
@SerializedName("screen_name")
val screenName: String
//...other fields
) : Parcelable {
@Parcelize
data class OnlineInfo(
val visible: Boolean,
val status: String,
@SerializedName("last_seen")
val lastSeen: Int?,
@SerializedName("is_online")
val isOnline: Boolean?,
@SerializedName("online_mobile")
val isOnlineMobile: Boolean?,
@SerializedName("app_id")
val appId: Int?
) : Parcelable
}
@@ -2,14 +2,14 @@ package com.meloda.fast.api.model
import org.json.JSONObject
class VKConversation() : VKModel(), Cloneable {
class oldVKConversation() : VKModel(), Cloneable {
override val attachmentType = VKAttachments.Type.NONE
companion object {
const val serialVersionUID: Long = 1L
var profiles = arrayListOf<VKUser>()
var profiles = arrayListOf<oldVKUser>()
var groups = arrayListOf<VKGroup>()
var conversationsCount: Int = 0
@@ -41,12 +41,12 @@ class VKConversation() : VKModel(), Cloneable {
var membersCount: Int = 0
var title: String? = null
var pinnedMessage: VKMessage? = null
var pinnedMessage: oldVKMessage? = null
var intState: Int = 0
var state: State = State.IN
var lastMessage: VKMessage = VKMessage()
var lastMessage: oldVKMessage = oldVKMessage()
var isGroupChannel: Boolean = false
@@ -54,7 +54,7 @@ class VKConversation() : VKModel(), Cloneable {
var photo100: String = ""
var photo200: String = ""
var peerUser: VKUser? = null
var peerUser: oldVKUser? = null
var peerGroup: VKGroup? = null
@@ -87,7 +87,7 @@ class VKConversation() : VKModel(), Cloneable {
if (title?.isBlank() == true) title = null
it.optJSONObject("pinned_message")?.let { pinned ->
pinnedMessage = VKMessage(pinned)
pinnedMessage = oldVKMessage(pinned)
}
state = State.fromString(it.optString("state"))
@@ -112,7 +112,7 @@ class VKConversation() : VKModel(), Cloneable {
override fun toString() = title ?: ""
public override fun clone() = super.clone() as VKConversation
public override fun clone() = super.clone() as oldVKConversation
enum class Type(val value: String) {
NULL("null"),
@@ -4,15 +4,15 @@ import android.util.ArrayMap
import com.meloda.fast.api.VKUtil
import org.json.JSONObject
open class VKMessage() : VKModel() {
open class oldVKMessage() : VKModel() {
override val attachmentType = VKAttachments.Type.NONE
companion object {
var profiles = arrayListOf<VKUser>()
var profiles = arrayListOf<oldVKUser>()
var groups = arrayListOf<VKGroup>()
var conversations = arrayListOf<VKConversation>()
var conversations = arrayListOf<oldVKConversation>()
const val serialVersionUID: Long = 1L
@@ -97,13 +97,13 @@ open class VKMessage() : VKModel() {
var attachments: ArrayList<VKModel> = arrayListOf()
var fwdMessages: ArrayList<VKMessage> = arrayListOf()
var fwdMessages: ArrayList<oldVKMessage> = arrayListOf()
var replyMessage: VKMessage? = null
var replyMessage: oldVKMessage? = null
var action: VKMessageAction? = null
var fromUser: VKUser? = null
var fromUser: oldVKUser? = null
var fromGroup: VKGroup? = null
@@ -126,15 +126,15 @@ open class VKMessage() : VKModel() {
}
o.optJSONArray("fwd_messages")?.let {
val fwdMessages = ArrayList<VKMessage>(it.length())
val fwdMessages = ArrayList<oldVKMessage>(it.length())
for (i in 0 until it.length()) {
fwdMessages.add(VKMessage(it.optJSONObject(i)))
fwdMessages.add(oldVKMessage(it.optJSONObject(i)))
}
this.fwdMessages = fwdMessages
}
o.optJSONObject("reply_message")?.let {
replyMessage = VKMessage(it)
replyMessage = oldVKMessage(it)
}
o.optJSONObject("action")?.let {
@@ -142,7 +142,7 @@ open class VKMessage() : VKModel() {
}
}
fun getForwardedMessages() = ArrayList<VKMessage>().apply {
fun getForwardedMessages() = ArrayList<oldVKMessage>().apply {
for (model in fwdMessages) add(model)
}
@@ -3,7 +3,7 @@ package com.meloda.fast.api.model
import org.json.JSONArray
import org.json.JSONObject
open class VKUser() : VKModel() {
open class oldVKUser() : VKModel() {
override val attachmentType = VKAttachments.Type.NONE
@@ -12,11 +12,11 @@ open class VKUser() : VKModel() {
var friendsCount: Int = 0
fun parse(array: JSONArray): ArrayList<VKUser> {
val users = ArrayList<VKUser>()
fun parse(array: JSONArray): ArrayList<oldVKUser> {
val users = ArrayList<oldVKUser>()
for (i in 0 until array.length()) {
users.add(VKUser(array.optJSONObject(i)))
users.add(oldVKUser(array.optJSONObject(i)))
}
return users
@@ -2,10 +2,9 @@ package com.meloda.fast.api.network
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.meloda.fast.api.network.datasource.AuthDataSource
import com.meloda.fast.api.network.datasource.ConversationsDataSource
import com.meloda.fast.api.network.repo.AuthRepo
import com.meloda.fast.api.network.repo.ConversationsRepo
import com.meloda.fast.api.network.repo.UsersRepo
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
@@ -60,16 +59,12 @@ class VKModules {
fun provideAuthRepo(retrofit: Retrofit): AuthRepo =
retrofit.create(AuthRepo::class.java)
@Provides
fun provideAuthDataSource(repo: AuthRepo): AuthDataSource =
AuthDataSource(repo)
@Provides
fun provideConversationsRepo(retrofit: Retrofit): ConversationsRepo =
retrofit.create(ConversationsRepo::class.java)
@Provides
fun provideConversationsDataSource(repo: ConversationsRepo): ConversationsDataSource =
ConversationsDataSource(repo)
fun provideUsersRepo(retrofit: Retrofit): UsersRepo =
retrofit.create(UsersRepo::class.java)
}
@@ -14,6 +14,10 @@ object VKUrls {
const val get = "$API/messages.getConversations"
}
object Users {
const val getById = "$API/users.get"
}
}
@@ -1,12 +0,0 @@
package com.meloda.fast.api.network.datasource
import com.meloda.fast.api.network.repo.AuthRepo
import javax.inject.Inject
class AuthDataSource @Inject constructor(
private val repo: AuthRepo
) : AuthRepo {
override suspend fun auth(param: Map<String, String?>) = repo.auth(param)
override suspend fun sendSms(validationSid: String) = repo.sendSms(validationSid)
}
@@ -1,13 +0,0 @@
package com.meloda.fast.api.network.datasource
import com.meloda.fast.api.network.repo.ConversationsRepo
import com.meloda.fast.api.network.request.ConversationsGetRequest
import javax.inject.Inject
class ConversationsDataSource @Inject constructor(
private val repo: ConversationsRepo
) : ConversationsRepo {
override suspend fun getAllChats(param: ConversationsGetRequest) = repo.getAllChats(param)
}
@@ -0,0 +1,17 @@
package com.meloda.fast.api.network.repo
import com.meloda.fast.api.base.ApiResponse
import com.meloda.fast.api.model.base.BaseVkUser
import com.meloda.fast.api.network.Answer
import com.meloda.fast.api.network.VKUrls
import com.meloda.fast.api.network.request.UsersGetRequest
import dagger.Component
import retrofit2.http.Body
import retrofit2.http.POST
interface UsersRepo {
@POST(VKUrls.Users.getById)
suspend fun getById(@Body param: UsersGetRequest): Answer<ApiResponse<List<BaseVkUser>>>
}
@@ -0,0 +1,14 @@
package com.meloda.fast.api.network.request
import android.os.Parcelable
import com.google.gson.annotations.SerializedName
import kotlinx.parcelize.Parcelize
@Parcelize
data class UsersGetRequest(
@SerializedName("user_ids")
val usersIds: List<Int>,
val fields: String? = null,
@SerializedName("nom_case")
val nomCase: String? = null
) : Parcelable
@@ -2,8 +2,8 @@ package com.meloda.fast.api.network.response
import android.os.Parcelable
import com.google.gson.annotations.SerializedName
import com.meloda.fast.api.model.BaseVKConversation
import com.meloda.fast.api.model.BaseVKMessage
import com.meloda.fast.api.model.base.BaseVkConversation
import com.meloda.fast.api.model.base.BaseVkMessage
import kotlinx.parcelize.Parcelize
@Parcelize
@@ -16,7 +16,7 @@ data class ConversationsGetResponse(
@Parcelize
data class ConversationsResponseItems(
val conversation: BaseVKConversation,
val conversation: BaseVkConversation,
@SerializedName("last_message")
val lastMessage: BaseVKMessage
val lastMessage: BaseVkMessage
) : Parcelable
@@ -0,0 +1,5 @@
package com.meloda.fast.api.network.response
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
@@ -8,15 +8,15 @@ import android.widget.AdapterView
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
@Suppress("UNCHECKED_CAST", "unused", "MemberVisibilityCanBePrivate", "CanBeParameter")
abstract class BaseAdapter<Item : BaseItem, VH : BaseHolder>(
@Suppress("MemberVisibilityCanBePrivate", "unused")
abstract class BaseAdapter<Item, VH : BaseHolder>(
var context: Context,
values: ArrayList<Item>,
values: MutableList<Item>,
diffUtil: DiffUtil.ItemCallback<Item>
) : ListAdapter<Item, VH>(diffUtil) {
val cleanValues = arrayListOf<Item>()
val values = arrayListOf<Item>()
val cleanValues = mutableListOf<Item>()
val values = mutableListOf<Item>()
init {
addAll(values)
@@ -94,13 +94,11 @@ abstract class BaseAdapter<Item : BaseItem, VH : BaseHolder>(
return inflater.inflate(resId, viewGroup, attachToRoot)
}
fun updateValues(arrayList: ArrayList<Item>) {
fun updateValues(list: MutableList<Item>) {
values.clear()
values += arrayList
values += list
}
fun updateValues(list: List<Item>) = updateValues(ArrayList(list))
override fun onBindViewHolder(holder: VH, position: Int) {
onBindItemViewHolder(holder, position)
}
@@ -122,8 +120,6 @@ abstract class BaseAdapter<Item : BaseItem, VH : BaseHolder>(
return values.size
}
val size get() = itemCount
private fun onBindItemViewHolder(holder: VH, position: Int) {
initListeners(holder.itemView, position)
holder.bind(position)
@@ -6,7 +6,9 @@ import androidx.viewbinding.ViewBinding
abstract class BaseHolder(v: View) : RecyclerView.ViewHolder(v) {
open fun bind(position: Int) {}
open fun bind(position: Int) {
bind(position, null)
}
open fun bind(position: Int, payloads: MutableList<Any>?) {}
@@ -12,9 +12,9 @@ import com.meloda.fast.database.storage.ChatsStorage
import com.meloda.fast.database.storage.GroupsStorage
import com.meloda.fast.database.storage.MessagesStorage
import com.meloda.fast.database.storage.UsersStorage
import com.meloda.fast.api.model.VKConversation
import com.meloda.fast.api.model.VKMessage
import com.meloda.fast.api.model.VKUser
import com.meloda.fast.api.model.oldVKConversation
import com.meloda.fast.api.model.oldVKMessage
import com.meloda.fast.api.model.oldVKUser
import java.util.*
object CacheStorage {
@@ -74,22 +74,22 @@ object CacheStorage {
for (value in values) {
when (tableName) {
TABLE_USERS -> {
usersStorage.cacheValue(contentValues, value as VKUser)
usersStorage.cacheValue(contentValues, value as oldVKUser)
break
}
TABLE_FRIENDS -> {
usersStorage.cacheValue(
contentValues,
value as VKUser,
value as oldVKUser,
Bundle().apply { putBoolean("toFriends", true) })
break
}
TABLE_MESSAGES -> {
messagesStorage.cacheValue(contentValues, value as VKMessage)
messagesStorage.cacheValue(contentValues, value as oldVKMessage)
break
}
TABLE_CHATS -> {
chatsStorage.cacheValue(contentValues, value as VKConversation)
chatsStorage.cacheValue(contentValues, value as oldVKConversation)
break
}
}
@@ -25,18 +25,18 @@ import com.meloda.fast.database.DatabaseKeys.TYPE
import com.meloda.fast.database.DatabaseKeys.UNREAD_COUNT
import com.meloda.fast.database.DatabaseUtils.TABLE_CHATS
import com.meloda.fast.database.base.Storage
import com.meloda.fast.api.model.VKConversation
import com.meloda.fast.api.model.oldVKConversation
import com.meloda.fast.api.VKUtil
import org.json.JSONObject
@WorkerThread
class ChatsStorage : Storage<VKConversation>() {
class ChatsStorage : Storage<oldVKConversation>() {
override val tag = "ChatsStorage"
override fun getAllValues(): ArrayList<VKConversation> {
override fun getAllValues(): ArrayList<oldVKConversation> {
val cursor = CacheStorage.selectCursor(TABLE_CHATS)
val conversations = ArrayList<VKConversation>()
val conversations = ArrayList<oldVKConversation>()
while (cursor.moveToNext()) conversations.add(parseValue(cursor))
@@ -46,7 +46,7 @@ class ChatsStorage : Storage<VKConversation>() {
}
@WorkerThread
override fun insertValues(values: ArrayList<VKConversation>, params: Bundle?) {
override fun insertValues(values: ArrayList<oldVKConversation>, params: Bundle?) {
if (values.isEmpty()) return
database.beginTransaction()
@@ -68,7 +68,7 @@ class ChatsStorage : Storage<VKConversation>() {
}
@WorkerThread
override fun cacheValue(values: ContentValues, value: VKConversation, params: Bundle?) {
override fun cacheValue(values: ContentValues, value: oldVKConversation, params: Bundle?) {
values.put(CONVERSATION_ID, value.id)
values.put(IS_ALLOWED, value.isAllowed)
values.put(NOT_ALLOWED_REASON, value.notAllowedReason.value)
@@ -99,12 +99,12 @@ class ChatsStorage : Storage<VKConversation>() {
}
@WorkerThread
override fun parseValue(cursor: Cursor): VKConversation {
val conversation = VKConversation()
override fun parseValue(cursor: Cursor): oldVKConversation {
val conversation = oldVKConversation()
conversation.id = CacheStorage.getInt(cursor, CONVERSATION_ID)
conversation.isAllowed = CacheStorage.getInt(cursor, IS_ALLOWED) == 1
conversation.notAllowedReason = VKConversation.Reason.fromInt(
conversation.notAllowedReason = oldVKConversation.Reason.fromInt(
CacheStorage.getInt(cursor, NOT_ALLOWED_REASON)
)
conversation.inReadMessageId = CacheStorage.getInt(cursor, IN_READ_MESSAGE_ID)
@@ -23,22 +23,22 @@ import com.meloda.fast.database.DatabaseKeys.TEXT
import com.meloda.fast.database.DatabaseUtils.TABLE_MESSAGES
import com.meloda.fast.database.base.Storage
import com.meloda.fast.util.Utils
import com.meloda.fast.api.model.VKMessage
import com.meloda.fast.api.model.oldVKMessage
import com.meloda.fast.api.model.VKMessageAction
import com.meloda.fast.api.model.VKModel
import java.util.stream.Collectors
@WorkerThread
@Suppress("UNCHECKED_CAST")
class MessagesStorage : Storage<VKMessage>() {
class MessagesStorage : Storage<oldVKMessage>() {
override val tag = "MessagesStorage"
@WorkerThread
fun getMessagesHistory(peerId: Int): ArrayList<VKMessage> {
fun getMessagesHistory(peerId: Int): ArrayList<oldVKMessage> {
val cursor = CacheStorage.selectCursor(TABLE_MESSAGES, PEER_ID, peerId)
val messages = ArrayList<VKMessage>(cursor.count)
val messages = ArrayList<oldVKMessage>(cursor.count)
while (cursor.moveToNext()) messages.add(parseValue(cursor))
cursor.close()
@@ -47,7 +47,7 @@ class MessagesStorage : Storage<VKMessage>() {
}
@WorkerThread
fun getMessageById(messageId: Int): VKMessage? {
fun getMessageById(messageId: Int): oldVKMessage? {
val cursor = CacheStorage.selectCursor(TABLE_MESSAGES, MESSAGE_ID, messageId)
if (cursor.moveToFirst()) {
@@ -60,9 +60,9 @@ class MessagesStorage : Storage<VKMessage>() {
return null
}
override fun getAllValues(): ArrayList<VKMessage> {
override fun getAllValues(): ArrayList<oldVKMessage> {
val cursor = selectCursor(TABLE_MESSAGES)
val messages = ArrayList<VKMessage>()
val messages = ArrayList<oldVKMessage>()
while (cursor.moveToNext()) messages.add(parseValue(cursor))
@@ -72,7 +72,7 @@ class MessagesStorage : Storage<VKMessage>() {
}
@WorkerThread
override fun insertValues(values: ArrayList<VKMessage>, params: Bundle?) {
override fun insertValues(values: ArrayList<oldVKMessage>, params: Bundle?) {
if (values.isEmpty()) return
database.beginTransaction()
@@ -94,7 +94,7 @@ class MessagesStorage : Storage<VKMessage>() {
}
@WorkerThread
override fun cacheValue(values: ContentValues, value: VKMessage, params: Bundle?) {
override fun cacheValue(values: ContentValues, value: oldVKMessage, params: Bundle?) {
values.put(MESSAGE_ID, value.id)
values.put(DATE, value.date)
values.put(PEER_ID, value.peerId)
@@ -131,8 +131,8 @@ class MessagesStorage : Storage<VKMessage>() {
}
@WorkerThread
override fun parseValue(cursor: Cursor): VKMessage {
val message = VKMessage()
override fun parseValue(cursor: Cursor): oldVKMessage {
val message = oldVKMessage()
message.id = CacheStorage.getInt(cursor, MESSAGE_ID)
message.date = CacheStorage.getInt(cursor, DATE)
@@ -162,7 +162,7 @@ class MessagesStorage : Storage<VKMessage>() {
val ids = arrayListOf<Int>()
for (s in split) ids.add(s.toInt())
val fwdMessages = arrayListOf<VKMessage>()
val fwdMessages = arrayListOf<oldVKMessage>()
ids.forEach {
val fwdMessage = getMessageById(it)
@@ -7,7 +7,7 @@ import android.util.Log
import androidx.annotation.WorkerThread
import com.meloda.fast.api.UserConfig
import com.meloda.fast.api.VKUtil
import com.meloda.fast.api.model.VKUser
import com.meloda.fast.api.model.oldVKUser
import com.meloda.fast.database.CacheStorage
import com.meloda.fast.database.DatabaseKeys.DEACTIVATED
import com.meloda.fast.database.DatabaseKeys.FIRST_NAME
@@ -29,15 +29,15 @@ import com.meloda.fast.database.base.Storage
import org.json.JSONObject
@WorkerThread
class UsersStorage : Storage<VKUser>() {
class UsersStorage : Storage<oldVKUser>() {
override val tag = "UsersStorage"
@WorkerThread
fun getUsers(ids: IntArray): ArrayList<VKUser> {
fun getUsers(ids: IntArray): ArrayList<oldVKUser> {
val cursor = CacheStorage.selectCursor(TABLE_USERS, USER_ID, ids)
val users = ArrayList<VKUser>(cursor.count)
val users = ArrayList<oldVKUser>(cursor.count)
while (cursor.moveToNext()) users.add(parseValue(cursor))
cursor.close()
@@ -45,14 +45,14 @@ class UsersStorage : Storage<VKUser>() {
}
@WorkerThread
fun getUser(userId: Int): VKUser? {
fun getUser(userId: Int): oldVKUser? {
val user = getUsers(intArrayOf(userId))
return if (user.isNotEmpty()) user[0] else null
}
@WorkerThread
fun getFriends(userId: Int, onlyOnline: Boolean = false): ArrayList<VKUser> {
fun getFriends(userId: Int, onlyOnline: Boolean = false): ArrayList<oldVKUser> {
val cursor = QueryBuilder.query()
.select("*")
.from(TABLE_FRIENDS)
@@ -61,7 +61,7 @@ class UsersStorage : Storage<VKUser>() {
.where("friends.${USER_ID} = $userId")
.asCursor(database)
val users = ArrayList<VKUser>(cursor.count)
val users = ArrayList<oldVKUser>(cursor.count)
while (cursor.moveToNext()) {
val userOnline = CacheStorage.getInt(cursor, IS_ONLINE) == 1
@@ -76,9 +76,9 @@ class UsersStorage : Storage<VKUser>() {
return users
}
override fun getAllValues(): ArrayList<VKUser> {
override fun getAllValues(): ArrayList<oldVKUser> {
val cursor = CacheStorage.selectCursor(TABLE_USERS)
val users = ArrayList<VKUser>()
val users = ArrayList<oldVKUser>()
while (cursor.moveToNext()) users.add(parseValue(cursor))
@@ -88,7 +88,7 @@ class UsersStorage : Storage<VKUser>() {
}
@WorkerThread
override fun insertValues(values: ArrayList<VKUser>, params: Bundle?) {
override fun insertValues(values: ArrayList<oldVKUser>, params: Bundle?) {
if (values.isEmpty()) return
val toFriends = params?.getBoolean("toFriends") ?: false
@@ -112,7 +112,7 @@ class UsersStorage : Storage<VKUser>() {
}
@WorkerThread
override fun cacheValue(values: ContentValues, value: VKUser, params: Bundle?) {
override fun cacheValue(values: ContentValues, value: oldVKUser, params: Bundle?) {
val toFriends = params?.getBoolean("toFriends") ?: false
if (toFriends) {
@@ -144,8 +144,8 @@ class UsersStorage : Storage<VKUser>() {
}
@WorkerThread
override fun parseValue(cursor: Cursor): VKUser {
val user = VKUser()
override fun parseValue(cursor: Cursor): oldVKUser {
val user = oldVKUser()
user.userId = CacheStorage.getInt(cursor, USER_ID)
user.firstName = CacheStorage.getString(cursor, FIRST_NAME)
@@ -0,0 +1 @@
package com.meloda.fast.di
@@ -3,30 +3,33 @@ package com.meloda.fast.screens.messages
import android.content.Context
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import com.meloda.fast.api.model.VKConversation
import com.meloda.fast.api.model.VkConversation
import com.meloda.fast.base.adapter.BaseAdapter
import com.meloda.fast.base.adapter.BindingHolder
import com.meloda.fast.databinding.ItemConversationBinding
class ConversationsAdapter(context: Context, values: ArrayList<VKConversation>) :
BaseAdapter<VKConversation, ConversationsAdapter.ItemHolder>(
class ConversationsAdapter(context: Context, values: MutableList<VkConversation>) :
BaseAdapter<VkConversation, ConversationsAdapter.ItemHolder>(
context, values, COMPARATOR
) {
companion object {
private val COMPARATOR = object : DiffUtil.ItemCallback<VKConversation>() {
private val COMPARATOR = object : DiffUtil.ItemCallback<VkConversation>() {
override fun areItemsTheSame(
oldItem: VKConversation,
newItem: VKConversation
oldItem: VkConversation,
newItem: VkConversation
) = false
override fun areContentsTheSame(
oldItem: VKConversation,
newItem: VKConversation
oldItem: VkConversation,
newItem: VkConversation
) = false
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
ItemHolder(ItemConversationBinding.inflate(inflater, parent, false))
inner class ItemHolder(binding: ItemConversationBinding) :
BindingHolder<ItemConversationBinding>(binding) {
@@ -35,7 +38,4 @@ class ConversationsAdapter(context: Context, values: ArrayList<VKConversation>)
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
ItemHolder(ItemConversationBinding.inflate(inflater, parent, false))
}
@@ -1,11 +1,16 @@
package com.meloda.fast.screens.messages
import android.os.Bundle
import android.util.Log
import android.view.View
import android.viewbinding.library.fragment.viewBinding
import androidx.core.view.isVisible
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import com.meloda.fast.R
import com.meloda.fast.api.LoadManager
import com.meloda.fast.api.model.VkConversation
import com.meloda.fast.api.model.VkMessage
import com.meloda.fast.base.BaseViewModelFragment
import com.meloda.fast.base.viewmodel.StartProgressEvent
import com.meloda.fast.base.viewmodel.StopProgressEvent
@@ -13,12 +18,21 @@ import com.meloda.fast.base.viewmodel.VKEvent
import com.meloda.fast.databinding.FragmentConversationsBinding
import com.meloda.fast.util.AndroidUtils
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
import kotlin.math.roundToInt
import kotlin.system.measureTimeMillis
@AndroidEntryPoint
class ConversationsFragment :
BaseViewModelFragment<ConversationsViewModel>(R.layout.fragment_conversations) {
companion object {
val TAG: String = ConversationsFragment::class.java.name
}
// @Inject
// lateinit var loadManager: LoadManager
override val viewModel: ConversationsViewModel by viewModels()
private val binding: FragmentConversationsBinding by viewBinding()
@@ -29,25 +43,29 @@ class ConversationsFragment :
prepareViews()
adapter = ConversationsAdapter(requireContext(), mutableListOf())
binding.recyclerView.adapter = adapter
viewModel.loadConversations()
}
override fun onEvent(event: VKEvent) {
super.onEvent(event)
when (event) {
is ConversationsLoaded -> return
is ConversationsLoaded -> prepareData(event)
is StartProgressEvent -> onProgressStarted()
is StopProgressEvent -> onProgressStopped()
}
}
private fun onProgressStarted() {
if (adapter.isEmpty())
binding.progressBar.isVisible = true
binding.progressBar.isVisible = adapter.isEmpty()
binding.refreshLayout.isRefreshing = adapter.isNotEmpty()
}
private fun onProgressStopped() {
binding.progressBar.isVisible = false
binding.refreshLayout.isRefreshing = false
}
private fun prepareViews() {
@@ -78,8 +96,46 @@ class ConversationsFragment :
R.attr.colorAccent
)
)
setOnRefreshListener { }
setOnRefreshListener { viewModel.loadConversations() }
}
}
private fun prepareData(event: ConversationsLoaded) {
val conversations = mutableListOf<VkConversation>()
val timeInMillis = measureTimeMillis {
for (i in event.conversations.indices) {
val baseConversation = event.conversations[i]
val baseMessage = event.messages[i]
conversations += VkConversation(
id = baseConversation.peer.id,
title = baseConversation.chatSettings?.title,
lastMessage = VkMessage(
id = baseMessage.id,
text = baseMessage.text,
isOut = baseMessage.out == 1,
peerId = baseMessage.peerId,
fromId = baseMessage.fromId,
date = baseMessage.date
)
)
}
}
Log.d(TAG, "prepareData: $timeInMillis ms")
fillRecyclerView(conversations)
lifecycleScope.launch {
LoadManager.users.load(listOf(1, 2, 3))
}
}
private fun fillRecyclerView(values: List<VkConversation>) {
adapter.values.clear()
adapter.values += values
adapter.notifyDataSetChanged()
}
}
@@ -2,11 +2,13 @@ package com.meloda.fast.screens.messages
import androidx.lifecycle.viewModelScope
import com.meloda.fast.api.VKConstants
import com.meloda.fast.api.model.BaseVKConversation
import com.meloda.fast.api.model.BaseVKMessage
import com.meloda.fast.api.model.base.BaseVkConversation
import com.meloda.fast.api.model.base.BaseVkMessage
import com.meloda.fast.api.network.repo.ConversationsRepo
import com.meloda.fast.api.network.request.ConversationsGetRequest
import com.meloda.fast.base.viewmodel.BaseViewModel
import com.meloda.fast.base.viewmodel.StartProgressEvent
import com.meloda.fast.base.viewmodel.StopProgressEvent
import com.meloda.fast.base.viewmodel.VKEvent
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
@@ -44,10 +46,10 @@ class ConversationsViewModel @Inject constructor(
val i = 0
},
onStart = {
val i = 0
sendEvent(StartProgressEvent)
},
onEnd = {
val i = 0
sendEvent(StopProgressEvent)
})
}
}
@@ -55,6 +57,6 @@ class ConversationsViewModel @Inject constructor(
data class ConversationsLoaded(
val count: Int,
val unreadCount: Int,
val messages: List<BaseVKMessage>,
val conversations: List<BaseVKConversation>
val messages: List<BaseVkMessage>,
val conversations: List<BaseVkConversation>
) : VKEvent()
@@ -17,7 +17,7 @@ import kotlin.math.abs
object VKUtils {
fun getUserOnline(user: VKUser): String {
fun getUserOnline(user: oldVKUser): String {
val r = AppGlobal.resources
return if (user.isOnline) {
if (user.isOnlineMobile) {
@@ -39,8 +39,8 @@ object VKUtils {
fun getUserOnlineIcon(
context: Context,
conversation: VKConversation?,
peerUser: VKUser?
conversation: oldVKConversation?,
peerUser: oldVKUser?
): Drawable? {
return if (conversation != null) {
if (conversation.isUser() && peerUser != null) {
@@ -65,7 +65,7 @@ object VKUtils {
}
}
fun getUserOnlineIcon(context: Context, user: VKUser): Drawable? {
fun getUserOnlineIcon(context: Context, user: oldVKUser): Drawable? {
return getUserOnlineIcon(context, null, user)
}
@@ -175,7 +175,7 @@ object VKUtils {
return null
}
fun getFwdText(context: Context, forwardedMessages: List<VKMessage>): String {
fun getFwdText(context: Context, forwardedMessages: List<oldVKMessage>): String {
return if (forwardedMessages.isNotEmpty()) {
if (forwardedMessages.size > 1) {
context.getString(R.string.message_fwd_many, forwardedMessages.size).lowerCase()
@@ -188,7 +188,7 @@ object VKUtils {
@Deprecated("need to rewrite")
fun getActionText(
context: Context,
lastMessage: VKMessage
lastMessage: oldVKMessage
) {
lastMessage.action?.let {
@@ -245,7 +245,7 @@ object VKUtils {
}
}
fun getTime(context: Context, lastMessage: VKMessage): String {
fun getTime(context: Context, lastMessage: oldVKMessage): String {
val then = lastMessage.date * 1000L
val now = System.currentTimeMillis()
@@ -10,7 +10,7 @@ import com.google.android.material.snackbar.Snackbar
import com.meloda.fast.extensions.ContextExtensions.color
import com.meloda.fast.R
import com.meloda.fast.widget.CircleImageView
import com.meloda.fast.api.model.VKUser
import com.meloda.fast.api.model.oldVKUser
object ViewUtils {
@@ -31,7 +31,7 @@ object ViewUtils {
).show()
}
fun prepareNavigationHeader(view: View, user: VKUser) {
fun prepareNavigationHeader(view: View, user: oldVKUser) {
val profileName = view.findViewById<TextView>(R.id.headerName)
profileName.text = user.toString()
@@ -77,7 +77,7 @@
android:layout_marginEnd="8dp"
android:fontFamily="@font/tt_commons_medium"
android:singleLine="true"
android:textColor="?itemTitleColor"
android:textColor="#ff0000"
android:textSize="20sp"
tools:text="Title" />