diff --git a/.idea/dictionaries/meloda.xml b/.idea/dictionaries/meloda.xml
new file mode 100644
index 00000000..b44a8b27
--- /dev/null
+++ b/.idea/dictionaries/meloda.xml
@@ -0,0 +1,7 @@
+
+
+
+ podcast
+
+
+
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index 23a89bbb..7863a219 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -12,6 +12,12 @@
+
+
+
+
+
+
diff --git a/app/build.gradle b/app/build.gradle
index 53e892a1..80cbf240 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -6,7 +6,7 @@ plugins {
android {
compileSdkVersion 30
- buildToolsVersion "31.0.0-rc1"
+ buildToolsVersion "30.0.3"
defaultConfig {
applicationId "com.meloda.fast"
@@ -21,35 +21,38 @@ android {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
-
- debug {
- applicationIdSuffix '.debug'
- }
}
+
compileOptions {
coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
+
kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8.toString()
}
}
dependencies {
- implementation(name: 'mvp-debug', ext: 'aar')
+ implementation project(":mvp")
+ implementation project(":vksdk")
+ implementation project(":arrayutils")
+ implementation project(":netservices")
+ implementation project(":concurrent")
+ implementation project(":extensions")
- coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.1'
+ coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
implementation "org.jetbrains.kotlin:kotlin-stdlib:${kotlin_version}"
- implementation 'androidx.core:core-ktx:1.5.0-beta01'
+ implementation 'androidx.core:core-ktx:1.5.0-beta02'
implementation 'androidx.appcompat:appcompat:1.3.0-beta01'
implementation 'androidx.preference:preference-ktx:1.1.1'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.2.0-alpha01'
- implementation 'androidx.recyclerview:recyclerview:1.2.0-beta01'
+ implementation 'androidx.recyclerview:recyclerview:1.2.0-beta02'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.fragment:fragment-ktx:1.3.0'
implementation 'com.google.android.material:material:1.3.0'
diff --git a/app/libs/mvp-debug.aar b/app/libs/mvp-debug.aar
deleted file mode 100644
index b48ec4e0..00000000
Binary files a/app/libs/mvp-debug.aar and /dev/null differ
diff --git a/app/release/app-release.apk b/app/release/app-release.apk
index 891db446..6034a02d 100644
Binary files a/app/release/app-release.apk and b/app/release/app-release.apk differ
diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json
index ab8eb66e..d7d1b834 100644
--- a/app/release/output-metadata.json
+++ b/app/release/output-metadata.json
@@ -4,7 +4,7 @@
"type": "APK",
"kind": "Directory"
},
- "applicationId": "ru.melod1n.project.vkm",
+ "applicationId": "com.meloda.fast",
"variantName": "processReleaseResources",
"elements": [
{
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index a47e3736..a5250609 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -12,7 +12,9 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
-
+
diff --git a/app/src/main/java/com/meloda/fast/api/UserConfig.kt b/app/src/main/java/com/meloda/fast/UserConfig.kt
similarity index 89%
rename from app/src/main/java/com/meloda/fast/api/UserConfig.kt
rename to app/src/main/java/com/meloda/fast/UserConfig.kt
index ebd40491..80aa623b 100644
--- a/app/src/main/java/com/meloda/fast/api/UserConfig.kt
+++ b/app/src/main/java/com/meloda/fast/UserConfig.kt
@@ -1,4 +1,4 @@
-package com.meloda.fast.api
+package com.meloda.fast
import android.text.TextUtils
import com.meloda.fast.common.AppGlobal
@@ -21,7 +21,7 @@ object UserConfig {
}
fun restore() {
- token = AppGlobal.preferences.getString(TOKEN, "")!!
+ token = AppGlobal.preferences.getString(TOKEN, "") ?: ""
userId = AppGlobal.preferences.getInt(USER_ID, -1)
}
diff --git a/app/src/main/java/com/meloda/fast/VKLongPollParser.kt b/app/src/main/java/com/meloda/fast/VKLongPollParser.kt
new file mode 100644
index 00000000..c6017076
--- /dev/null
+++ b/app/src/main/java/com/meloda/fast/VKLongPollParser.kt
@@ -0,0 +1,160 @@
+package com.meloda.fast
+
+import android.util.Log
+import androidx.annotation.WorkerThread
+import com.meloda.concurrent.EventInfo
+import com.meloda.concurrent.TaskManager
+import com.meloda.vksdk.VKApiKeys
+import com.meloda.vksdk.model.VKMessage
+import com.meloda.vksdk.util.VKUtil
+import org.json.JSONArray
+
+@Suppress("UNCHECKED_CAST")
+object VKLongPollParser {
+
+
+ @WorkerThread
+ fun parse(updates: JSONArray) {
+ if (updates.length() == 0) {
+ return
+ }
+
+ for (i in 0 until updates.length()) {
+ val item = updates.optJSONArray(i)
+ when (item.optInt(0)) {
+ 2 -> messageSetFlags(item)
+ 3 -> messageClearFlags(item)
+ 4 -> messageEvent(item)
+ 5 -> messageEdit(item)
+ }
+ }
+ }
+
+ fun parseEvent(eventInfo: EventInfo<*>, onMessagesListener: OnMessagesListener) {
+ when (eventInfo.key) {
+ VKApiKeys.NEW_MESSAGE.value -> onMessagesListener.onNewMessage(eventInfo.data as VKMessage)
+ VKApiKeys.EDIT_MESSAGE.value -> onMessagesListener.onEditMessage(eventInfo.data as VKMessage)
+ VKApiKeys.RESTORE_MESSAGE.value -> onMessagesListener.onRestoredMessage(eventInfo.data as VKMessage)
+ VKApiKeys.DELETE_MESSAGE.value -> {
+ val array = eventInfo.data as Array
+ onMessagesListener.onDeleteMessage(array[0], array[1])
+ }
+ VKApiKeys.READ_MESSAGE.value -> {
+ val array = eventInfo.data as Array
+ onMessagesListener.onReadMessage(array[0], array[1])
+ }
+ }
+ }
+
+ private const val TAG = "VKLongPollParser"
+
+ private fun messageEvent(item: JSONArray) {
+ val message = VKUtil.parseLongPollMessage(item)
+
+ TaskManager.execute {
+ if (message.isFromUser()) {
+// VKUtil.searchUser(message.fromId)?.let { message.fromUser = it }
+ } else {
+// VKUtil.searchGroup(message.fromId)?.let { message.fromGroup = it }
+ }
+
+// MemoryCache.getConversationById(message.peerId)?.let {
+// it.lastMessage = message
+// it.lastMessageId = message.messageId
+//
+// MemoryCache.put(it)
+// }
+//
+// MemoryCache.put(message)
+
+ val info = EventInfo(VKApiKeys.NEW_MESSAGE.name, message)
+
+ sendEvent(info)
+ }
+ }
+
+ private fun messageEdit(item: JSONArray) {
+ val message = VKUtil.parseLongPollMessage(item)
+ val info = EventInfo(VKApiKeys.EDIT_MESSAGE.name, message)
+
+// MemoryCache.put(message)
+
+ sendEvent(info)
+ }
+
+ private fun messageDelete(item: JSONArray) {
+ val messageId = item.optInt(1)
+ val peerId = item.optInt(3)
+ val info = EventInfo(VKApiKeys.DELETE_MESSAGE.name, arrayOf(peerId, messageId))
+
+// MemoryCache.deleteMessage(messageId)
+
+ sendEvent(info)
+ }
+
+ private fun messageRestored(item: JSONArray) {
+ val message = VKUtil.parseLongPollMessage(item)
+ val info = EventInfo(VKApiKeys.RESTORE_MESSAGE.name, message)
+
+// MemoryCache.put(message)
+
+ sendEvent(info)
+ }
+
+ private fun messageRead(item: JSONArray) {
+ val messageId = item.optInt(1)
+ val peerId = item.optInt(3)
+ val info = EventInfo(VKApiKeys.READ_MESSAGE.name, arrayOf(peerId, messageId))
+
+// MemoryCache.edit(MemoryCache.getMessageById(messageId)?.apply { isRead = true })
+
+ sendEvent(info)
+ }
+
+ private fun messageClearFlags(item: JSONArray) {
+ val id = item.optInt(1)
+ val flags = item.optInt(2)
+ if (VKUtil.isMessageHasFlag(flags, "cancel_spam")) {
+ Log.i(TAG, "Message with id $id: Not spam")
+ }
+ if (VKUtil.isMessageHasFlag(flags, "deleted")) {
+ messageRestored(item)
+ }
+ if (VKUtil.isMessageHasFlag(flags, "important")) {
+ Log.i(TAG, "Message with id $id: Not Important")
+ }
+ if (VKUtil.isMessageHasFlag(flags, "unread")) {
+ messageRead(item)
+ }
+ }
+
+ private fun messageSetFlags(item: JSONArray) {
+ val id = item.optInt(1)
+ val flags = item.optInt(2)
+ if (VKUtil.isMessageHasFlag(flags, "delete_for_all")) {
+ messageDelete(item)
+ }
+ if (VKUtil.isMessageHasFlag(flags, "deleted")) {
+ messageDelete(item)
+ }
+ if (VKUtil.isMessageHasFlag(flags, "spam")) {
+ Log.i(TAG, "Message with id $id: Spam")
+ }
+ if (VKUtil.isMessageHasFlag(flags, "important")) {
+ Log.i(TAG, "Message with id $id: Important")
+ }
+ }
+
+ private fun sendEvent(eventInfo: EventInfo<*>) {
+ TaskManager.sendEvent(eventInfo)
+ }
+
+ interface OnMessagesListener {
+ fun onNewMessage(message: VKMessage)
+ fun onEditMessage(message: VKMessage)
+ fun onRestoredMessage(message: VKMessage)
+ fun onDeleteMessage(peerId: Int, messageId: Int)
+ fun onReadMessage(peerId: Int, messageId: Int)
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/activity/DropUserDataActivity.kt b/app/src/main/java/com/meloda/fast/activity/DropUserDataActivity.kt
index 6d0593bf..d398bf0f 100644
--- a/app/src/main/java/com/meloda/fast/activity/DropUserDataActivity.kt
+++ b/app/src/main/java/com/meloda/fast/activity/DropUserDataActivity.kt
@@ -2,10 +2,8 @@ package com.meloda.fast.activity
import android.content.Intent
import android.os.Bundle
-import com.meloda.fast.api.UserConfig
+import com.meloda.fast.UserConfig
import com.meloda.fast.base.BaseActivity
-import com.meloda.fast.common.AppGlobal
-import com.meloda.fast.common.TaskManager
class DropUserDataActivity : BaseActivity() {
@@ -14,9 +12,9 @@ class DropUserDataActivity : BaseActivity() {
UserConfig.clear()
- TaskManager.execute { AppGlobal.database.clearAllTables() }
+// TaskManager.execute { AppGlobal.database.clearAllTables() }
- startActivity(Intent(this, MainActivityDeprecated::class.java))
+ startActivity(Intent(this, MainActivity::class.java))
finishAffinity()
}
diff --git a/app/src/main/java/com/meloda/fast/activity/LoginActivityDeprecated.kt b/app/src/main/java/com/meloda/fast/activity/LoginActivityDeprecated.kt
index 99e9424c..9fda684b 100644
--- a/app/src/main/java/com/meloda/fast/activity/LoginActivityDeprecated.kt
+++ b/app/src/main/java/com/meloda/fast/activity/LoginActivityDeprecated.kt
@@ -10,14 +10,14 @@ import android.webkit.*
import android.widget.ProgressBar
import androidx.core.view.isVisible
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
+import com.meloda.extensions.ContextExtensions.color
+import com.meloda.extensions.ContextExtensions.drawable
+import com.meloda.extensions.DrawableExtensions.tint
import com.meloda.fast.R
-import com.meloda.fast.api.UserConfig
-import com.meloda.fast.api.VKAuth
+import com.meloda.fast.UserConfig
import com.meloda.fast.base.BaseActivity
-import com.meloda.fast.extensions.ContextExtensions.color
-import com.meloda.fast.extensions.ContextExtensions.drawable
-import com.meloda.fast.extensions.DrawableExtensions.tint
import com.meloda.fast.widget.Toolbar
+import com.meloda.vksdk.VKAuth
class LoginActivityDeprecated : BaseActivity() {
@@ -125,7 +125,7 @@ class LoginActivityDeprecated : BaseActivity() {
UserConfig.save()
finishAffinity()
- startActivity(Intent(this, MainActivityDeprecated::class.java))
+ startActivity(Intent(this, MainActivity::class.java))
}
} catch (e: Exception) {
e.printStackTrace()
diff --git a/app/src/main/java/com/meloda/fast/activity/MainActivityDeprecated.kt b/app/src/main/java/com/meloda/fast/activity/MainActivity.kt
similarity index 85%
rename from app/src/main/java/com/meloda/fast/activity/MainActivityDeprecated.kt
rename to app/src/main/java/com/meloda/fast/activity/MainActivity.kt
index 627bf48c..4392b0f4 100644
--- a/app/src/main/java/com/meloda/fast/activity/MainActivityDeprecated.kt
+++ b/app/src/main/java/com/meloda/fast/activity/MainActivity.kt
@@ -9,31 +9,27 @@ import androidx.core.view.isVisible
import androidx.drawerlayout.widget.DrawerLayout
import com.google.android.material.bottomnavigation.BottomNavigationView
import com.google.android.material.navigation.NavigationView
+import com.meloda.extensions.ContextExtensions.color
+import com.meloda.extensions.ContextExtensions.drawable
+import com.meloda.extensions.DrawableExtensions.tint
import com.meloda.fast.R
-import com.meloda.fast.api.UserConfig
-import com.meloda.fast.api.VKApiKeys
-import com.meloda.fast.api.model.VKUser
+import com.meloda.fast.UserConfig
import com.meloda.fast.base.BaseActivity
import com.meloda.fast.common.AppGlobal
import com.meloda.fast.common.FragmentSwitcher
-import com.meloda.fast.common.TaskManager
import com.meloda.fast.common.TimeManager
import com.meloda.fast.dialog.AccountDialog
-import com.meloda.fast.extensions.ContextExtensions.color
-import com.meloda.fast.extensions.ContextExtensions.drawable
-import com.meloda.fast.extensions.DrawableExtensions.tint
-import com.meloda.fast.fragment.FragmentConversationsDeprecated
-import com.meloda.fast.fragment.FragmentFriendsDeprecated
-import com.meloda.fast.fragment.SettingsFragment
-import com.meloda.fast.fragment.LoginFragment
-import com.meloda.fast.listener.OnResponseListener
+import com.meloda.fast.fragment.*
import com.meloda.fast.service.LongPollService
import com.meloda.fast.util.AndroidUtils
import com.meloda.fast.util.ViewUtils
import com.meloda.fast.widget.Toolbar
+import com.meloda.vksdk.VKApi
+import com.meloda.vksdk.model.VKUser
+import java.util.*
-class MainActivityDeprecated : BaseActivity(),
+class MainActivity : BaseActivity(),
NavigationView.OnNavigationItemSelectedListener,
BottomNavigationView.OnNavigationItemSelectedListener {
@@ -56,8 +52,10 @@ class MainActivityDeprecated : BaseActivity(),
// checkLogin()
if (UserConfig.isLoggedIn()) {
+ VKApi.init(Locale.getDefault().language, UserConfig.token, AppGlobal.handler)
+
supportFragmentManager.beginTransaction()
- .replace(R.id.fragmentContainer, FragmentConversationsDeprecated())
+ .replace(R.id.fragmentContainer, ChatsFragment())
.commit()
} else {
bottomBar.isVisible = false
@@ -192,17 +190,18 @@ class MainActivityDeprecated : BaseActivity(),
private fun loadProfileInfo() {
if (AndroidUtils.hasConnection()) {
- TaskManager.loadUser(VKApiKeys.UPDATE_USER, UserConfig.userId,
- object : OnResponseListener {
- override fun onResponse(response: VKUser) {
- prepareNavigationHeader(response)
- openMainScreen()
- }
-
- override fun onError(t: Throwable) {
- openMainScreen()
- }
- })
+// TaskManager.loadUser(
+// VKApiKeys.UPDATE_USER, UserConfig.userId,
+// object : OnResponseListener {
+// override fun onResponse(response: VKUser) {
+// prepareNavigationHeader(response)
+// openMainScreen()
+// }
+//
+// override fun onError(t: Throwable) {
+// openMainScreen()
+// }
+// })
}
}
diff --git a/app/src/main/java/com/meloda/fast/activity/MessagesActivityDeprecated.kt b/app/src/main/java/com/meloda/fast/activity/MessagesActivityDeprecated.kt
index 575dd96f..8da1b952 100644
--- a/app/src/main/java/com/meloda/fast/activity/MessagesActivityDeprecated.kt
+++ b/app/src/main/java/com/meloda/fast/activity/MessagesActivityDeprecated.kt
@@ -14,24 +14,23 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.amulyakhare.textdrawable.TextDrawable
+import com.meloda.extensions.ContextExtensions.color
+import com.meloda.extensions.DrawableExtensions.tint
import com.meloda.fast.R
import com.meloda.fast.activity.ui.presenter.MessagesPresenterDeprecated
import com.meloda.fast.activity.ui.view.MessagesViewDeprecated
-import com.meloda.fast.api.model.VKConversation
-import com.meloda.fast.api.model.VKGroup
-import com.meloda.fast.api.model.VKModel
-import com.meloda.fast.api.model.VKUser
import com.meloda.fast.base.BaseActivity
import com.meloda.fast.common.AppGlobal
import com.meloda.fast.dialog.ProfileDialog
-import com.meloda.fast.extensions.ContextExtensions.color
-import com.meloda.fast.extensions.DrawableExtensions.tint
-import com.meloda.fast.extensions.ImageViewExtensions.loadImage
import com.meloda.fast.fragment.SettingsFragment
import com.meloda.fast.util.KeyboardUtils
import com.meloda.fast.util.TextUtils
import com.meloda.fast.util.ViewUtils
import com.meloda.fast.widget.CircleImageView
+import com.meloda.vksdk.model.VKConversation
+import com.meloda.vksdk.model.VKGroup
+import com.meloda.vksdk.model.VKModel
+import com.meloda.vksdk.model.VKUser
class MessagesActivityDeprecated : BaseActivity(), MessagesViewDeprecated {
@@ -140,7 +139,7 @@ class MessagesActivityDeprecated : BaseActivity(), MessagesViewDeprecated {
chatAvatar.setImageDrawable(placeholder)
- chatAvatar.loadImage(avatar, placeholder)
+// chatAvatar.loadImage(avatar, placeholder)
toolbar.setOnClickListener { presenterDeprecated.openProfile() }
diff --git a/app/src/main/java/com/meloda/fast/activity/SettingsActivityDeprecated.kt b/app/src/main/java/com/meloda/fast/activity/SettingsActivityDeprecated.kt
index a0172b70..2c964d52 100644
--- a/app/src/main/java/com/meloda/fast/activity/SettingsActivityDeprecated.kt
+++ b/app/src/main/java/com/meloda/fast/activity/SettingsActivityDeprecated.kt
@@ -1,10 +1,10 @@
package com.meloda.fast.activity
import android.os.Bundle
+import com.meloda.extensions.ContextExtensions.drawable
import com.meloda.fast.R
import com.meloda.fast.base.BaseActivity
import com.meloda.fast.common.FragmentSwitcher
-import com.meloda.fast.extensions.ContextExtensions.drawable
import com.meloda.fast.fragment.SettingsFragment
import com.meloda.fast.util.ColorUtils
import com.meloda.fast.widget.Toolbar
diff --git a/app/src/main/java/com/meloda/fast/activity/UpdateActivityDeprecated.kt b/app/src/main/java/com/meloda/fast/activity/UpdateActivityDeprecated.kt
index fbe10158..eab5b026 100644
--- a/app/src/main/java/com/meloda/fast/activity/UpdateActivityDeprecated.kt
+++ b/app/src/main/java/com/meloda/fast/activity/UpdateActivityDeprecated.kt
@@ -18,19 +18,19 @@ import androidx.core.text.HtmlCompat
import androidx.core.view.isVisible
import com.github.rahatarmanahmed.cpv.CircularProgressView
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
+import com.meloda.concurrent.TaskManager
+import com.meloda.extensions.ContextExtensions.drawable
+import com.meloda.extensions.FloatExtensions.int
import com.meloda.fast.BuildConfig
import com.meloda.fast.R
import com.meloda.fast.base.BaseActivity
import com.meloda.fast.common.AppGlobal
-import com.meloda.fast.common.TaskManager
import com.meloda.fast.common.UpdateManager
-import com.meloda.fast.extensions.ContextExtensions.drawable
-import com.meloda.fast.extensions.FloatExtensions.int
-import com.meloda.fast.listener.OnResponseListener
import com.meloda.fast.model.NewUpdateInfo
import com.meloda.fast.receiver.DownloadUpdateReceiver
import com.meloda.fast.util.AndroidUtils
import com.meloda.fast.util.TimeUtils
+import com.meloda.vksdk.OnResponseListener
import java.io.File
import java.text.SimpleDateFormat
import java.util.*
diff --git a/app/src/main/java/com/meloda/fast/activity/ui/presenter/MessagesPresenterDeprecated.kt b/app/src/main/java/com/meloda/fast/activity/ui/presenter/MessagesPresenterDeprecated.kt
index cd4b40a4..1315330e 100644
--- a/app/src/main/java/com/meloda/fast/activity/ui/presenter/MessagesPresenterDeprecated.kt
+++ b/app/src/main/java/com/meloda/fast/activity/ui/presenter/MessagesPresenterDeprecated.kt
@@ -1,23 +1,21 @@
package com.meloda.fast.activity.ui.presenter
import androidx.recyclerview.widget.RecyclerView
+import com.meloda.concurrent.EventInfo
+import com.meloda.concurrent.TaskManager
import com.meloda.fast.R
+import com.meloda.fast.UserConfig
import com.meloda.fast.activity.ui.repository.MessagesRepositoryDeprecated
import com.meloda.fast.activity.ui.view.MessagesViewDeprecated
import com.meloda.fast.adapter.MessagesAdapterDeprecated
-import com.meloda.fast.api.UserConfig
-import com.meloda.fast.api.VKApiKeys
-import com.meloda.fast.api.model.VKConversation
-import com.meloda.fast.api.model.VKMessage
-import com.meloda.fast.api.model.VKModel
import com.meloda.fast.common.AppGlobal
-import com.meloda.fast.common.TaskManager
-import com.meloda.fast.database.MemoryCache
-import com.meloda.fast.event.EventInfo
import com.meloda.fast.listener.ItemClickListener
import com.meloda.fast.listener.ItemLongClickListener
-import com.meloda.mvp.MvpOnLoadListener
+import com.meloda.mvp.MvpOnResponseListener
import com.meloda.mvp.MvpPresenter
+import com.meloda.vksdk.model.VKConversation
+import com.meloda.vksdk.model.VKMessage
+import com.meloda.vksdk.model.VKModel
import kotlin.random.Random
class MessagesPresenterDeprecated(viewState: MessagesViewDeprecated) :
@@ -74,7 +72,7 @@ class MessagesPresenterDeprecated(viewState: MessagesViewDeprecated) :
}
private fun getCachedConversation(peerId: Int) {
- repository.getCachedConversation(peerId, object : MvpOnLoadListener {
+ repository.getCachedConversation(peerId, object : MvpOnResponseListener {
override fun onResponse(response: VKConversation) {
conversation = response
@@ -82,7 +80,7 @@ class MessagesPresenterDeprecated(viewState: MessagesViewDeprecated) :
refreshConversation(response)
getCachedMessages(peerId, 0, DEFAULT_MESSAGES_COUNT,
- object : MvpOnLoadListener {
+ object : MvpOnResponseListener {
override fun onResponse(response: Any?) {
loadConversation(peerId)
loadMessages(peerId)
@@ -107,7 +105,7 @@ class MessagesPresenterDeprecated(viewState: MessagesViewDeprecated) :
viewState.hideProgressBar()
}
- repository.loadConversation(peerId, object : MvpOnLoadListener {
+ repository.loadConversation(peerId, object : MvpOnResponseListener {
override fun onResponse(response: VKConversation) {
conversation = response
@@ -129,7 +127,7 @@ class MessagesPresenterDeprecated(viewState: MessagesViewDeprecated) :
repository.getChatInfo(
conversation,
- object : MvpOnLoadListener {
+ object : MvpOnResponseListener {
override fun onResponse(response: String) {
viewState.setChatInfo(response)
}
@@ -154,10 +152,10 @@ class MessagesPresenterDeprecated(viewState: MessagesViewDeprecated) :
peerId: Int,
offset: Int = 0,
count: Int = DEFAULT_MESSAGES_COUNT,
- listener: MvpOnLoadListener? = null
+ listener: MvpOnResponseListener? = null
) {
repository.getCachedMessages(peerId, offset, count,
- object : MvpOnLoadListener> {
+ object : MvpOnResponseListener> {
override fun onResponse(response: ArrayList) {
viewState.hideProgressBar()
fillAdapter(response, offset)
@@ -177,7 +175,7 @@ class MessagesPresenterDeprecated(viewState: MessagesViewDeprecated) :
private fun loadMessages(peerId: Int, offset: Int = 0, count: Int = DEFAULT_MESSAGES_COUNT) {
repository.loadMessages(peerId, offset, count,
- object : MvpOnLoadListener> {
+ object : MvpOnResponseListener> {
override fun onResponse(response: ArrayList) {
fillAdapter(response, offset)
}
@@ -237,12 +235,12 @@ class MessagesPresenterDeprecated(viewState: MessagesViewDeprecated) :
adapter.addMessage(message, true, scrollToBottom)
- repository.sendMessage(peerId, text, message.randomId, object : MvpOnLoadListener {
+ repository.sendMessage(peerId, text, message.randomId, object : MvpOnResponseListener {
override fun onResponse(response: Int) {
- message.messageId = response
+ message.id = response
- TaskManager.execute { MemoryCache.put(message) }
- TaskManager.loadMessage(VKApiKeys.UPDATE_MESSAGE, response)
+// TaskManager.execute { MemoryCache.put(message) }
+// TaskManager.loadMessage(VKApiKeys.UPDATE_MESSAGE, response)
}
override fun onError(t: Throwable) {
diff --git a/app/src/main/java/com/meloda/fast/activity/ui/repository/MessagesRepositoryDeprecated.kt b/app/src/main/java/com/meloda/fast/activity/ui/repository/MessagesRepositoryDeprecated.kt
index c53ec243..40fe8696 100644
--- a/app/src/main/java/com/meloda/fast/activity/ui/repository/MessagesRepositoryDeprecated.kt
+++ b/app/src/main/java/com/meloda/fast/activity/ui/repository/MessagesRepositoryDeprecated.kt
@@ -1,21 +1,16 @@
package com.meloda.fast.activity.ui.repository
+import com.meloda.concurrent.TaskManager
import com.meloda.fast.R
-import com.meloda.fast.api.VKApi
-import com.meloda.fast.api.VKApiKeys
-import com.meloda.fast.api.model.VKConversation
-import com.meloda.fast.api.model.VKGroup
-import com.meloda.fast.api.model.VKMessage
-import com.meloda.fast.api.model.VKUser
-import com.meloda.fast.api.util.VKUtil
import com.meloda.fast.common.AppGlobal
-import com.meloda.fast.common.TaskManager
-import com.meloda.fast.database.MemoryCache
-import com.meloda.fast.extensions.ArrayExtensions.asArrayList
-import com.meloda.fast.listener.OnResponseListener
-import com.meloda.fast.util.ArrayUtils
-import com.meloda.mvp.MvpOnLoadListener
+import com.meloda.mvp.MvpOnResponseListener
import com.meloda.mvp.MvpRepository
+import com.meloda.vksdk.OnResponseListener
+import com.meloda.vksdk.VKApi
+import com.meloda.vksdk.VKConstants
+import com.meloda.vksdk.model.VKConversation
+import com.meloda.vksdk.model.VKMessage
+import com.meloda.vksdk.util.VKUtil
import java.util.*
class MessagesRepositoryDeprecated : MvpRepository() {
@@ -24,7 +19,7 @@ class MessagesRepositoryDeprecated : MvpRepository() {
peerId: Int,
offset: Int,
count: Int,
- listener: MvpOnLoadListener>
+ listener: MvpOnResponseListener>
) {
TaskManager.execute {
VKApi.messages()
@@ -32,7 +27,7 @@ class MessagesRepositoryDeprecated : MvpRepository() {
.peerId(peerId)
.reversed(false)
.extended(true)
- .fields(VKUser.DEFAULT_FIELDS + "," + VKGroup.DEFAULT_FIELDS)
+ .fields(VKConstants.USER_FIELDS + "," + VKConstants.GROUP_FIELDS)
.offset(offset)
.count(count)
.executeArray(
@@ -42,9 +37,9 @@ class MessagesRepositoryDeprecated : MvpRepository() {
TaskManager.execute {
cacheLoadedMessages(response)
- MemoryCache.putUsers(VKMessage.profiles)
- MemoryCache.putGroups(VKMessage.groups)
- MemoryCache.putConversations(VKMessage.conversations)
+// MemoryCache.putUsers(VKMessage.profiles)
+// MemoryCache.putGroups(VKMessage.groups)
+// MemoryCache.putConversations(VKMessage.conversations)
VKUtil.sortMessagesByDate(response, false)
@@ -61,57 +56,57 @@ class MessagesRepositoryDeprecated : MvpRepository() {
fun getCachedMessages(
peerId: Int, offset: Int, count: Int,
- listener: MvpOnLoadListener>
+ listener: MvpOnResponseListener>
) {
TaskManager.execute {
- val messages = MemoryCache.getMessagesByPeerId(peerId).asArrayList()
-
- if (messages.isEmpty()) {
- sendError(listener, NullPointerException("Messages is empty"))
- return@execute
- }
-
- VKUtil.sortMessagesByDate(messages, false)
-
- val preparedMessages = ArrayUtils.cut(messages, offset, count)
-
- sendResponseArray(listener, preparedMessages)
+// val messages = MemoryCache.getMessagesByPeerId(peerId).asArrayList()
+//
+// if (messages.isEmpty()) {
+// sendError(listener, NullPointerException("Messages is empty"))
+// return@execute
+// }
+//
+// VKUtil.sortMessagesByDate(messages, false)
+//
+// val preparedMessages = ArrayUtils.cut(messages, offset, count)
+//
+// sendResponseArray(listener, preparedMessages)
}
}
- fun getCachedConversation(peerId: Int, listener: MvpOnLoadListener) {
+ fun getCachedConversation(peerId: Int, listener: MvpOnResponseListener) {
TaskManager.execute {
- val conversation = MemoryCache.getConversationById(peerId)
-
- if (conversation == null) {
- sendError(
- listener,
- NullPointerException("Conversation is not cached at the moment")
- )
- } else {
- sendResponse(listener, conversation)
- }
+// val conversation = MemoryCache.getConversationById(peerId)
+//
+// if (conversation == null) {
+// sendError(
+// listener,
+// NullPointerException("Conversation is not cached at the moment")
+// )
+// } else {
+// sendResponse(listener, conversation)
+// }
}
}
- fun loadConversation(peerId: Int, listener: MvpOnLoadListener) {
- TaskManager.loadConversation(
- VKApiKeys.UPDATE_CONVERSATION,
- peerId,
- object : OnResponseListener {
- override fun onResponse(response: VKConversation) {
- sendResponse(listener, response)
- }
-
- override fun onError(t: Throwable) {
- sendError(listener, t)
- }
- })
+ fun loadConversation(peerId: Int, listener: MvpOnResponseListener) {
+// TaskManager.loadConversation(
+// VKApiKeys.UPDATE_CONVERSATION,
+// peerId,
+// object : OnResponseListener {
+// override fun onResponse(response: VKConversation) {
+// sendResponse(listener, response)
+// }
+//
+// override fun onError(t: Throwable) {
+// sendError(listener, t)
+// }
+// })
}
- fun getChatInfo(conversation: VKConversation, listener: MvpOnLoadListener) {
+ fun getChatInfo(conversation: VKConversation, listener: MvpOnResponseListener) {
when (conversation.type) {
- VKConversation.TYPE_CHAT -> {
+ VKConversation.Type.CHAT -> {
sendResponse(
listener,
AppGlobal.resources.getString(
@@ -122,21 +117,21 @@ class MessagesRepositoryDeprecated : MvpRepository() {
)
)
}
- VKConversation.TYPE_USER -> {
- val user = VKUtil.searchUser(conversation.conversationId,
- object : OnResponseListener {
- override fun onResponse(response: VKUser) {
- sendResponse(listener, VKUtil.getUserOnline(response))
- }
-
- override fun onError(t: Throwable) {
- sendError(listener, t)
- }
- })
-
- user?.let {
- sendResponse(listener, VKUtil.getUserOnline(it))
- }
+ VKConversation.Type.USER -> {
+// val user = VKUtil.searchUser(conversation.conversationId,
+// object : OnResponseListener {
+// override fun onResponse(response: VKUser) {
+// sendResponse(listener, VKUtil.getUserOnline(response))
+// }
+//
+// override fun onError(t: Throwable) {
+// sendError(listener, t)
+// }
+// })
+//
+// user?.let {
+// sendResponse(listener, VKUtil.getUserOnline(it))
+// }
}
else -> {
sendResponse(listener, "")
@@ -148,7 +143,7 @@ class MessagesRepositoryDeprecated : MvpRepository() {
peerId: Int,
message: String,
randomId: Int,
- listener: MvpOnLoadListener
+ listener: MvpOnResponseListener
) {
TaskManager.execute {
VKApi.messages()
@@ -170,6 +165,6 @@ class MessagesRepositoryDeprecated : MvpRepository() {
}
private fun cacheLoadedMessages(messages: ArrayList) {
- MemoryCache.putMessages(messages)
+// MemoryCache.putMessages(messages)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/activity/ui/view/MessagesViewDeprecated.kt b/app/src/main/java/com/meloda/fast/activity/ui/view/MessagesViewDeprecated.kt
index 9198dd3d..ae5a28e8 100644
--- a/app/src/main/java/com/meloda/fast/activity/ui/view/MessagesViewDeprecated.kt
+++ b/app/src/main/java/com/meloda/fast/activity/ui/view/MessagesViewDeprecated.kt
@@ -1,7 +1,7 @@
package com.meloda.fast.activity.ui.view
-import com.meloda.fast.api.model.VKConversation
import com.meloda.mvp.MvpView
+import com.meloda.vksdk.model.VKConversation
interface MessagesViewDeprecated : MvpView {
diff --git a/app/src/main/java/com/meloda/fast/adapter/ChatsAdapter.kt b/app/src/main/java/com/meloda/fast/adapter/ChatsAdapter.kt
new file mode 100644
index 00000000..4e16ebf3
--- /dev/null
+++ b/app/src/main/java/com/meloda/fast/adapter/ChatsAdapter.kt
@@ -0,0 +1,71 @@
+package com.meloda.fast.adapter
+
+import android.content.Context
+import android.view.View
+import android.view.ViewGroup
+import androidx.recyclerview.widget.DiffUtil
+import com.meloda.concurrent.EventInfo
+import com.meloda.concurrent.TaskManager
+import com.meloda.fast.R
+import com.meloda.fast.VKLongPollParser
+import com.meloda.fast.adapter.diffutil.ConversationsCallback
+import com.meloda.fast.base.BaseAdapter
+import com.meloda.fast.base.BaseHolder
+import com.meloda.vksdk.model.VKConversation
+import com.meloda.vksdk.model.VKMessage
+
+class ChatsAdapter(context: Context, values: ArrayList) :
+ BaseAdapter(
+ context, values
+ ),
+ TaskManager.OnEventListener,
+ VKLongPollParser.OnMessagesListener {
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ return ViewHolder(view(R.layout.item_conversation, parent))
+ }
+
+ override fun notifyChanges(oldList: List, newList: List) {
+ val callback = ConversationsCallback(oldList, newList)
+ val diff = DiffUtil.calculateDiff(callback)
+
+ diff.dispatchUpdatesTo(this)
+ }
+
+ override fun onNewEvent(info: EventInfo<*>) {
+
+ }
+
+ inner class ViewHolder(v: View) : BaseHolder(v) {
+
+ override fun bind(position: Int, payloads: MutableList?) {
+ val conversation = getItem(position)
+ val lastMessage = conversation.lastMessage
+
+ TaskManager.execute {
+
+ }
+ }
+
+ }
+
+ override fun onNewMessage(message: VKMessage) {
+ TODO("Not yet implemented")
+ }
+
+ override fun onEditMessage(message: VKMessage) {
+ TODO("Not yet implemented")
+ }
+
+ override fun onRestoredMessage(message: VKMessage) {
+ TODO("Not yet implemented")
+ }
+
+ override fun onDeleteMessage(peerId: Int, messageId: Int) {
+ TODO("Not yet implemented")
+ }
+
+ override fun onReadMessage(peerId: Int, messageId: Int) {
+ TODO("Not yet implemented")
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/adapter/ConversationsAdapterDeprecated.kt b/app/src/main/java/com/meloda/fast/adapter/ConversationsAdapterDeprecated.kt
index be6e1251..ab7d6808 100644
--- a/app/src/main/java/com/meloda/fast/adapter/ConversationsAdapterDeprecated.kt
+++ b/app/src/main/java/com/meloda/fast/adapter/ConversationsAdapterDeprecated.kt
@@ -13,27 +13,27 @@ import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.TextView
import androidx.core.view.isVisible
-import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
+import com.meloda.concurrent.EventInfo
+import com.meloda.concurrent.TaskManager
+import com.meloda.extensions.ContextExtensions.color
import com.meloda.fast.R
+import com.meloda.fast.UserConfig
import com.meloda.fast.adapter.diffutil.ConversationsCallbackDeprecated
-import com.meloda.fast.api.UserConfig
-import com.meloda.fast.api.VKApiKeys
-import com.meloda.fast.api.model.VKConversation
-import com.meloda.fast.api.model.VKGroup
-import com.meloda.fast.api.model.VKMessage
-import com.meloda.fast.api.model.VKUser
-import com.meloda.fast.api.util.VKUtil
import com.meloda.fast.base.BaseAdapter
import com.meloda.fast.base.BaseHolder
import com.meloda.fast.common.AppGlobal
-import com.meloda.fast.common.TaskManager
-import com.meloda.fast.database.MemoryCache
-import com.meloda.fast.event.EventInfo
-import com.meloda.fast.extensions.ContextExtensions.color
-import com.meloda.fast.listener.OnResponseListener
+import com.meloda.fast.database.CacheStorage
+import com.meloda.fast.util.VKUtils
import com.meloda.fast.widget.CircleImageView
+import com.meloda.vksdk.OnResponseListener
+import com.meloda.vksdk.VKApiKeys
+import com.meloda.vksdk.model.VKConversation
+import com.meloda.vksdk.model.VKGroup
+import com.meloda.vksdk.model.VKMessage
+import com.meloda.vksdk.model.VKUser
+import com.meloda.vksdk.util.VKUtil
@Suppress("UNCHECKED_CAST")
@@ -62,22 +62,22 @@ class ConversationsAdapterDeprecated(
override fun onNewEvent(info: EventInfo<*>) {
when (info.key) {
- VKApiKeys.NEW_MESSAGE -> addMessage(info.data as VKMessage)
- VKApiKeys.EDIT_MESSAGE -> editMessage(info.data as VKMessage)
- VKApiKeys.RESTORE_MESSAGE -> restoreMessage(info.data as VKMessage)
- VKApiKeys.READ_MESSAGE -> readMessage(
+ VKApiKeys.NEW_MESSAGE.name -> addMessage(info.data as VKMessage)
+ VKApiKeys.EDIT_MESSAGE.name -> editMessage(info.data as VKMessage)
+ VKApiKeys.RESTORE_MESSAGE.name -> restoreMessage(info.data as VKMessage)
+ VKApiKeys.READ_MESSAGE.name -> readMessage(
(info.data as Array)[0],
(info.data as Array)[1]
)
- VKApiKeys.DELETE_MESSAGE -> deleteMessage(
+ VKApiKeys.DELETE_MESSAGE.name -> deleteMessage(
(info.data as Array)[0],
(info.data as Array)[1]
)
- VKApiKeys.UPDATE_CONVERSATION -> updateConversation(info.data as Int)
- VKApiKeys.UPDATE_MESSAGE -> updateMessage(info.data as Int)
- VKApiKeys.UPDATE_USER -> updateUsers(info.data as ArrayList)
- VKApiKeys.UPDATE_GROUP -> updateGroups(info.data as ArrayList)
+ VKApiKeys.UPDATE_CONVERSATION.name -> updateConversation(info.data as Int)
+ VKApiKeys.UPDATE_MESSAGE.name -> updateMessage(info.data as Int)
+ VKApiKeys.UPDATE_USER.name -> updateUsers(info.data as ArrayList)
+ VKApiKeys.UPDATE_GROUP.name -> updateGroups(info.data as ArrayList)
}
}
@@ -96,13 +96,6 @@ class ConversationsAdapterDeprecated(
holder.bind(position, payloads)
}
- fun notifyChanges(oldList: List, newList: List = values) {
- val callback = ConversationsCallbackDeprecated(oldList, newList)
- val diff = DiffUtil.calculateDiff(callback)
-
- diff.dispatchUpdatesTo(this)
- }
-
fun isLastItem() = currentPosition >= itemCount - 1
inner class ConversationHolder(v: View) : BaseHolder(v) {
@@ -125,25 +118,24 @@ class ConversationsAdapterDeprecated(
bind(position, mutableListOf())
}
- fun bind(position: Int, payloads: MutableList) {
+ override fun bind(position: Int, payloads: MutableList?) {
Log.d(TAG, "bind position: $position")
- val conversation = this@ConversationsAdapterDeprecated[position]
-
+ val conversation = getItem(position)
val lastMessage = conversation.lastMessage
TaskManager.execute {
val peerUser: VKUser? =
- if (conversation.isUser()) VKUtil.searchUser(conversation.conversationId) else null
+ if (conversation.isUser()) CacheStorage.usersStorage.getUser(conversation.id) else null
val peerGroup: VKGroup? =
- if (conversation.isGroup()) VKUtil.searchGroup(conversation.conversationId) else null
+ if (conversation.isGroup()) CacheStorage.groupsStorage.getGroup(conversation.id) else null
val fromUser: VKUser? =
- if (lastMessage.isFromUser()) VKUtil.searchUser(lastMessage.fromId) else null
+ if (lastMessage.isFromUser()) CacheStorage.usersStorage.getUser(lastMessage.fromId) else null
val fromGroup: VKGroup? =
- if (lastMessage.isFromGroup()) VKUtil.searchGroup(lastMessage.fromId) else null
+ if (lastMessage.isFromGroup()) CacheStorage.groupsStorage.getGroup(lastMessage.fromId) else null
conversation.peerUser = peerUser
conversation.peerGroup = peerGroup
@@ -154,7 +146,7 @@ class ConversationsAdapterDeprecated(
post {
val dialogTitle = setTitle(conversation, peerUser, peerGroup)
- if (payloads.isNotEmpty()) {
+ if (payloads != null && payloads.isNotEmpty()) {
for (payload in payloads) {
when (payload) {
ConversationsCallbackDeprecated.CONVERSATION -> {
@@ -264,7 +256,7 @@ class ConversationsAdapterDeprecated(
}
private fun setUserOnline(conversation: VKConversation, peerUser: VKUser?) {
- val onlineIcon = VKUtil.getUserOnlineIcon(context, conversation, peerUser)
+ val onlineIcon = VKUtils.getUserOnlineIcon(context, conversation, peerUser)
online.setImageDrawable(onlineIcon)
online.isVisible = onlineIcon != null
@@ -298,7 +290,7 @@ class ConversationsAdapterDeprecated(
peerUser: VKUser?,
peerGroup: VKGroup?
) {
- val dialogAvatarPlaceholder = VKUtil.getAvatarPlaceholder(context, dialogTitle)
+ val dialogAvatarPlaceholder = VKUtils.getAvatarPlaceholder(context, dialogTitle)
avatar.setImageDrawable(dialogAvatarPlaceholder)
@@ -310,11 +302,11 @@ class ConversationsAdapterDeprecated(
}
private fun setDialogType(conversation: VKConversation) {
- val dDialogType = VKUtil.getDialogType(context, conversation)
-
- type.setImageDrawable(dDialogType)
+// val dDialogType = VKUtil.getDialogType(context, conversation)
+//
+// type.setImageDrawable(dDialogType)
// type.isVisible = dDialogType != null
- type.isVisible = false
+// type.isVisible = false
}
private fun prepareAttachments(lastMessage: VKMessage) {
@@ -328,7 +320,7 @@ class ConversationsAdapterDeprecated(
when {
lastMessage.attachments.isNotEmpty() -> {
val attachmentString =
- VKUtil.getAttachmentText(context, lastMessage.attachments)
+ VKUtils.getAttachmentText(context, lastMessage.attachments)
val attachmentText =
if (lastMessage.text.isEmpty()) attachmentString else lastMessage.text
@@ -346,7 +338,7 @@ class ConversationsAdapterDeprecated(
}
val attachmentDrawable =
- VKUtil.getAttachmentDrawable(context, lastMessage.attachments)
+ VKUtils.getAttachmentDrawable(context, lastMessage.attachments)
text.text = span
attachments.isVisible = true
@@ -364,7 +356,8 @@ class ConversationsAdapterDeprecated(
// }
}
lastMessage.fwdMessages.isNotEmpty() -> {
- val fwdText = VKUtil.getFwdText(context, lastMessage.getForwardedMessages())
+ val fwdText =
+ VKUtils.getFwdText(context, lastMessage.getForwardedMessages())
val span = SpannableString(fwdText).apply {
setSpan(ForegroundColorSpan(colorHighlight), 0, fwdText.length, 0)
}
@@ -379,7 +372,7 @@ class ConversationsAdapterDeprecated(
}
}
} else {
- VKUtil.getActionText(context, lastMessage,
+ VKUtils.getActionText(context, lastMessage,
object : OnResponseListener {
override fun onResponse(response: String) {
val span = SpannableString(response).apply {
@@ -417,8 +410,8 @@ class ConversationsAdapterDeprecated(
private fun setIsRead(lastMessage: VKMessage, conversation: VKConversation) {
val isRead =
- ((lastMessage.isOut && conversation.outRead == conversation.lastMessageId ||
- !lastMessage.isOut && conversation.inRead == conversation.lastMessageId) && conversation.lastMessageId == lastMessage.messageId) && conversation.unreadCount == 0
+ ((lastMessage.isOut && conversation.outReadMessageId == conversation.lastMessageId ||
+ !lastMessage.isOut && conversation.inReadMessageId == conversation.lastMessageId) && conversation.lastMessageId == lastMessage.id) && conversation.unreadCount == 0
if (isRead) {
counter.visibility = View.GONE
@@ -437,7 +430,7 @@ class ConversationsAdapterDeprecated(
}
private fun setDate(lastMessage: VKMessage) {
- val dateText = VKUtil.getTime(context, lastMessage)
+ val dateText = VKUtils.getTime(context, lastMessage)
date.text = dateText
}
@@ -461,30 +454,30 @@ class ConversationsAdapterDeprecated(
add(0, conversation)
notifyChanges(oldList)
} else {
- TaskManager.loadConversation(
- VKApiKeys.UPDATE_CONVERSATION,
- message.peerId,
- null
- )
+// TaskManager.loadConversation(
+// VKApiKeys.UPDATE_CONVERSATION,
+// message.peerId,
+// null
+// )
TaskManager.execute {
- val cachedConversation = MemoryCache.getConversationById(message.peerId)
- if (cachedConversation != null) {
- add(0, prepareConversation(cachedConversation, message))
- post { notifyChanges(oldList) }
- return@execute
- }
+// val cachedConversation = MemoryCache.getConversationById(message.peerId)
+// if (cachedConversation != null) {
+// add(0, prepareConversation(cachedConversation, message))
+// post { notifyChanges(oldList) }
+// return@execute
+// }
val tempConversations = VKConversation().apply {
- conversationId = message.peerId
+ id = message.peerId
localId =
- if (VKUtil.isChatId(conversationId)) conversationId - 2000000000 else conversationId
+ if (VKUtil.isChatId(id)) id - 2000000000 else id
type =
- if (conversationId < 0) VKConversation.TYPE_GROUP else if (conversationId > 2000000000) VKConversation.TYPE_CHAT else VKConversation.TYPE_USER
+ if (id < 0) VKConversation.Type.GROUP else if (id > 2000000000) VKConversation.Type.CHAT else VKConversation.Type.USER
lastMessage = message
- lastMessageId = message.messageId
+ lastMessageId = message.id
}
add(0, tempConversations)
@@ -505,7 +498,7 @@ class ConversationsAdapterDeprecated(
val conversation = getItem(index)
- if (conversation.lastMessageId != message.messageId) return
+ if (conversation.lastMessageId != message.id) return
conversation.lastMessage = message
@@ -520,9 +513,9 @@ class ConversationsAdapterDeprecated(
val message = conversation.lastMessage
if (message.isInbox()) {
- conversation.inRead = messageId
+ conversation.inReadMessageId = messageId
} else {
- conversation.outRead = messageId
+ conversation.outReadMessageId = messageId
}
conversation.unreadCount = if (conversation.lastMessageId == messageId) {
@@ -546,32 +539,32 @@ class ConversationsAdapterDeprecated(
val dialog = oldDialog.clone()
- TaskManager.execute {
- val cachedMessages = MemoryCache.getMessagesByPeerId(dialog.conversationId)
- val messages = VKUtil.sortMessagesByDate(ArrayList(cachedMessages), true)
-
- if (messages.isEmpty()) {
- MemoryCache.deleteConversation(dialog.conversationId)
-
- AppGlobal.post {
- removeAt(index)
- notifyChanges(oldList)
- }
- } else {
- val lastMessage = messages[0]
-
- dialog.lastMessageId = lastMessage.messageId
- dialog.lastMessage = lastMessage
-
- set(index, dialog)
-
- VKUtil.sortConversationsByDate(values, true)
-
- AppGlobal.post {
- notifyChanges(oldList)
- }
- }
- }
+// TaskManager.execute {
+// val cachedMessages = MemoryCache.getMessagesByPeerId(dialog.conversationId)
+// val messages = VKUtil.sortMessagesByDate(ArrayList(cachedMessages), true)
+//
+// if (messages.isEmpty()) {
+// MemoryCache.deleteConversation(dialog.conversationId)
+//
+// AppGlobal.post {
+// removeAt(index)
+// notifyChanges(oldList)
+// }
+// } else {
+// val lastMessage = messages[0]
+//
+// dialog.lastMessageId = lastMessage.messageId
+// dialog.lastMessage = lastMessage
+//
+// set(index, dialog)
+//
+// VKUtil.sortConversationsByDate(values, true)
+//
+// AppGlobal.post {
+// notifyChanges(oldList)
+// }
+// }
+// }
}
@Deprecated("Message is bad")
@@ -584,27 +577,27 @@ class ConversationsAdapterDeprecated(
val dialog = oldDialog.clone()
- TaskManager.execute {
- val messages =
- MemoryCache.getMessagesByPeerId(dialog.conversationId).apply { addMessage(message) }
-
- VKUtil.sortMessagesByDate(ArrayList(messages), true)
-
- val lastMessage = messages[0]
-
- dialog.lastMessageId = lastMessage.messageId
- dialog.lastMessage = lastMessage
-
- set(index, dialog)
-
- VKUtil.sortConversationsByDate(values, true)
-
- AppGlobal.handler.post {
- notifyChanges(oldList)
-
+// TaskManager.execute {
+// val messages =
+// MemoryCache.getMessagesByPeerId(dialog.conversationId).apply { addMessage(message) }
+//
+// VKUtil.sortMessagesByDate(ArrayList(messages), true)
+//
+// val lastMessage = messages[0]
+//
+// dialog.lastMessageId = lastMessage.messageId
+// dialog.lastMessage = lastMessage
+//
+// set(index, dialog)
+//
+// VKUtil.sortConversationsByDate(values, true)
+//
+// AppGlobal.handler.post {
+// notifyChanges(oldList)
+//
// fragmentConversations.presenter.checkListIsEmpty(values)
- }
- }
+// }
+// }
}
private fun prepareConversation(
@@ -612,7 +605,7 @@ class ConversationsAdapterDeprecated(
newMessage: VKMessage
): VKConversation {
conversation.lastMessage = newMessage
- conversation.lastMessageId = newMessage.messageId
+ conversation.lastMessageId = newMessage.id
if (newMessage.isOut) {
conversation.unreadCount = 0
@@ -622,7 +615,7 @@ class ConversationsAdapterDeprecated(
}
if (newMessage.peerId == newMessage.fromId && newMessage.fromId == UserConfig.userId) { //для лс
- conversation.outRead = newMessage.messageId
+ conversation.outReadMessageId = newMessage.id
}
return conversation
@@ -630,7 +623,7 @@ class ConversationsAdapterDeprecated(
private fun searchConversationIndex(peerId: Int): Int {
for (i in values.indices) {
- if (getItem(i).conversationId == peerId) return i
+ if (getItem(i).id == peerId) return i
}
return -1
}
@@ -646,13 +639,18 @@ class ConversationsAdapterDeprecated(
val index = searchConversationIndex(peerId)
if (index == -1) return
- TaskManager.execute {
- val conversation = MemoryCache.getConversationById(peerId) ?: return@execute
-
- set(index, conversation)
-
- AppGlobal.post { notifyItemChanged(index, ConversationsCallbackDeprecated.CONVERSATION) }
- }
+// TaskManager.execute {
+// val conversation = MemoryCache.getConversationById(peerId) ?: return@execute
+//
+// set(index, conversation)
+//
+// AppGlobal.post {
+// notifyItemChanged(
+// index,
+// ConversationsCallbackDeprecated.CONVERSATION
+// )
+// }
+// }
}
private fun updateGroups(groupIds: ArrayList) {
@@ -681,12 +679,17 @@ class ConversationsAdapterDeprecated(
TaskManager.execute {
val conversation = getItem(index).clone()
- conversation.apply {
- lastMessageId = messageId
- lastMessage = MemoryCache.getMessageById(messageId) ?: return@execute
- }
+// conversation.apply {
+// lastMessageId = messageId
+// lastMessage = MemoryCache.getMessageById(messageId) ?: return@execute
+// }
- AppGlobal.handler.post { notifyItemChanged(index, ConversationsCallbackDeprecated.MESSAGE) }
+ AppGlobal.handler.post {
+ notifyItemChanged(
+ index,
+ ConversationsCallbackDeprecated.MESSAGE
+ )
+ }
}
}
diff --git a/app/src/main/java/com/meloda/fast/adapter/MessagesAdapterDeprecated.kt b/app/src/main/java/com/meloda/fast/adapter/MessagesAdapterDeprecated.kt
index c4dfe210..f26d73cc 100644
--- a/app/src/main/java/com/meloda/fast/adapter/MessagesAdapterDeprecated.kt
+++ b/app/src/main/java/com/meloda/fast/adapter/MessagesAdapterDeprecated.kt
@@ -1,9 +1,6 @@
package com.meloda.fast.adapter
import android.content.Context
-import android.graphics.Typeface
-import android.text.SpannableString
-import android.text.style.StyleSpan
import android.util.Log
import android.view.View
import android.view.ViewGroup
@@ -12,24 +9,20 @@ import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.view.isVisible
import androidx.recyclerview.widget.LinearLayoutManager
+import com.meloda.concurrent.EventInfo
+import com.meloda.concurrent.TaskManager
+import com.meloda.extensions.FloatExtensions.int
import com.meloda.fast.BuildConfig
import com.meloda.fast.R
import com.meloda.fast.activity.MessagesActivityDeprecated
-import com.meloda.fast.api.VKApiKeys
-import com.meloda.fast.api.model.*
-import com.meloda.fast.api.util.VKUtil
import com.meloda.fast.base.BaseAdapter
import com.meloda.fast.base.BaseHolder
-import com.meloda.fast.common.AppGlobal
-import com.meloda.fast.common.TaskManager
-import com.meloda.fast.database.MemoryCache
-import com.meloda.fast.event.EventInfo
-import com.meloda.fast.extensions.FloatExtensions.int
-import com.meloda.fast.listener.OnResponseListener
import com.meloda.fast.util.AndroidUtils
-import com.meloda.fast.util.ImageUtils
import com.meloda.fast.widget.BoundedLinearLayout
import com.meloda.fast.widget.CircleImageView
+import com.meloda.vksdk.VKApiKeys
+import com.meloda.vksdk.model.*
+import com.meloda.vksdk.util.VKUtil
import java.text.SimpleDateFormat
import java.util.*
import kotlin.math.abs
@@ -75,23 +68,23 @@ class MessagesAdapterDeprecated(
override fun onNewEvent(info: EventInfo<*>) {
when (info.key) {
- VKApiKeys.NEW_MESSAGE -> addMessage(info.data as VKMessage)
+ VKApiKeys.NEW_MESSAGE.name -> addMessage(info.data as VKMessage)
- VKApiKeys.READ_MESSAGE -> readMessage(
+ VKApiKeys.READ_MESSAGE.name -> readMessage(
(info.data as Array)[0],
(info.data as Array)[1]
)
- VKApiKeys.RESTORE_MESSAGE -> restoreMessage(info.data as VKMessage)
- VKApiKeys.EDIT_MESSAGE -> editMessage(info.data as VKMessage)
- VKApiKeys.DELETE_MESSAGE -> deleteMessage(
+ VKApiKeys.RESTORE_MESSAGE.name -> restoreMessage(info.data as VKMessage)
+ VKApiKeys.EDIT_MESSAGE.name -> editMessage(info.data as VKMessage)
+ VKApiKeys.DELETE_MESSAGE.name -> deleteMessage(
(info.data as Array)[0],
(info.data as Array)[1]
)
- VKApiKeys.UPDATE_MESSAGE -> updateMessage(info.data as Int)
- VKApiKeys.UPDATE_USER -> updateUser(info.data as ArrayList)
- VKApiKeys.UPDATE_GROUP -> updateGroup(info.data as ArrayList)
+ VKApiKeys.UPDATE_MESSAGE.name -> updateMessage(info.data as Int)
+ VKApiKeys.UPDATE_USER.name -> updateUser(info.data as ArrayList)
+ VKApiKeys.UPDATE_GROUP.name -> updateGroup(info.data as ArrayList)
else -> return
}
@@ -157,12 +150,12 @@ class MessagesAdapterDeprecated(
val message = this[position]
- if (message.isUnreaded()) {
- TaskManager.readMessage(
- VKApiKeys.READ_MESSAGE,
- conversation.conversationId,
- message.messageId
- )
+ if (message.isRead.not()) {
+// TaskManager.readMessage(
+// VKApiKeys.READ_MESSAGE,
+// conversation.conversationId,
+// message.messageId
+// )
}
}
@@ -192,10 +185,10 @@ class MessagesAdapterDeprecated(
val avatarString = conversation.photo100
- val placeHolder = VKUtil.getAvatarPlaceholder(context, conversation.title)
+// val placeHolder = VKUtil.getAvatarPlaceholder(context, conversation.title)
- avatar.setImageDrawable(placeHolder)
- ImageUtils.loadImage(avatarString, avatar, placeHolder)
+// avatar.setImageDrawable(placeHolder)
+// ImageUtils.loadImage(avatarString, avatar, placeHolder)
title.text = conversation.title
@@ -216,23 +209,23 @@ class MessagesAdapterDeprecated(
val group = searchGroup(message)
val name =
- (if (group == null && !VKGroup.isGroupId(message.fromId)) user?.firstName else group?.name)
+ (if (group == null && !VKUtil.isGroupId(message.fromId)) user?.firstName else group?.name)
?: "null"
- VKUtil.getActionText(context, message, object : OnResponseListener {
-
- override fun onResponse(response: String) {
- val actionText = "$name $response"
-
- val spannable = SpannableString(actionText)
- spannable.setSpan(StyleSpan(Typeface.BOLD), 0, name.length, 0)
-
- text.text = spannable
- }
-
- override fun onError(t: Throwable) {
- }
- })
+// VKUtil.getActionText(context, message, object : OnResponseListener {
+//
+// override fun onResponse(response: String) {
+// val actionText = "$name $response"
+//
+// val spannable = SpannableString(actionText)
+// spannable.setSpan(StyleSpan(Typeface.BOLD), 0, name.length, 0)
+//
+// text.text = spannable
+// }
+//
+// override fun onError(t: Throwable) {
+// }
+// })
post { text.isVisible = true }
}
@@ -348,7 +341,7 @@ class MessagesAdapterDeprecated(
is VKVideo -> video(message, attachments)
is VKLink -> link(message, attachments)
is VKAudio -> audio(message, attachments)
- is VKDoc -> doc(message, attachments)
+ is VKDocument -> doc(message, attachments)
}
}
}
@@ -414,14 +407,14 @@ class MessagesAdapterDeprecated(
}
fun loadAvatarImage(message: VKMessage, user: VKUser?, group: VKGroup?, avatar: ImageView) {
- val dialogTitle = VKUtil.getMessageTitle(message, user, group)
- val avatarPlaceholder = VKUtil.getAvatarPlaceholder(context, dialogTitle)
-
- avatar.setImageDrawable(avatarPlaceholder)
-
- val avatarString = VKUtil.getUserAvatar(message, user, group)
-
- ImageUtils.loadImage(avatarString, avatar, avatarPlaceholder)
+// val dialogTitle = VKUtil.getMessageTitle(message, user, group)
+// val avatarPlaceholder = VKUtil.getAvatarPlaceholder(context, dialogTitle)
+//
+// avatar.setImageDrawable(avatarPlaceholder)
+//
+// val avatarString = VKUtil.getUserAvatar(message, user, group)
+//
+// ImageUtils.loadImage(avatarString, avatar, avatarPlaceholder)
}
}
@@ -436,13 +429,15 @@ class MessagesAdapterDeprecated(
private fun searchUser(message: VKMessage): VKUser? {
if (!message.isFromUser()) return null
- return VKUtil.searchUser(message.fromId)
+// return VKUtil.searchUser(message.fromId)
+ return null
}
private fun searchGroup(message: VKMessage): VKGroup? {
if (!message.isFromGroup()) return null
- return VKUtil.searchGroup(message.fromId)
+// return VKUtil.searchGroup(message.fromId)
+ return null
}
private fun updateGroup(groupIds: ArrayList) {
@@ -488,7 +483,7 @@ class MessagesAdapterDeprecated(
for (i in values.indices) {
val item = getItem(i)
- if (item.messageId == messageId) {
+ if (item.id == messageId) {
index = i
break
}
@@ -496,18 +491,18 @@ class MessagesAdapterDeprecated(
if (index == -1) return
- TaskManager.execute {
- AppGlobal.database.messages.getById(messageId)?.let {
- values[index] = it
-
- post { notifyItemChanged(index) }
- }
- }
+// TaskManager.execute {
+// AppGlobal.database.messages.getById(messageId)?.let {
+// values[index] = it
+//
+// post { notifyItemChanged(index) }
+// }
+// }
}
private fun searchMessagePosition(messageId: Int): Int {
for (i in values.indices) {
- if (getItem(i).messageId == messageId) return i
+ if (getItem(i).id == messageId) return i
}
return -1
@@ -523,7 +518,7 @@ class MessagesAdapterDeprecated(
fun addMessage(message: VKMessage, fromApp: Boolean = false, withScroll: Boolean = false) {
val randomId = message.randomId
- if (randomId > 0 && containsRandomId(message.randomId) || message.peerId != conversation.conversationId) return
+ if (randomId > 0 && containsRandomId(message.randomId) || message.peerId != conversation.id) return
add(message)
@@ -537,7 +532,7 @@ class MessagesAdapterDeprecated(
}
private fun readMessage(peerId: Int, messageId: Int) {
- if (peerId != conversation.conversationId) return
+ if (peerId != conversation.id) return
val index = searchMessagePosition(messageId)
if (index == -1) return
@@ -548,21 +543,21 @@ class MessagesAdapterDeprecated(
notifyDataSetChanged()
if (message.isInbox()) {
- conversation.inRead = messageId
+ conversation.inReadMessageId = messageId
} else {
- conversation.outRead = messageId
+ conversation.outReadMessageId = messageId
}
conversation.unreadCount--
- TaskManager.execute {
- MemoryCache.put(message)
- MemoryCache.put(conversation)
- }
+// TaskManager.execute {
+// MemoryCache.put(message)
+// MemoryCache.put(conversation)
+// }
}
fun editMessage(message: VKMessage) {
- val index = searchMessagePosition(message.messageId)
+ val index = searchMessagePosition(message.id)
if (index == -1) return
set(index, message)
@@ -570,7 +565,7 @@ class MessagesAdapterDeprecated(
}
fun deleteMessage(messageId: Int, peerId: Int) {
- if (peerId != conversation.conversationId) return
+ if (peerId != conversation.id) return
val index = searchMessagePosition(messageId)
if (index == -1) return
@@ -581,7 +576,7 @@ class MessagesAdapterDeprecated(
//TODO: кривое сообщение
fun restoreMessage(message: VKMessage) {
- if (message.peerId != conversation.conversationId) return
+ if (message.peerId != conversation.id) return
updateValues(VKUtil.sortMessagesByDate(values.apply { add(message) }, false))
notifyDataSetChanged()
diff --git a/app/src/main/java/com/meloda/fast/adapter/UsersAdapterDeprecated.kt b/app/src/main/java/com/meloda/fast/adapter/UsersAdapterDeprecated.kt
index 5ec90755..20e3f03a 100644
--- a/app/src/main/java/com/meloda/fast/adapter/UsersAdapterDeprecated.kt
+++ b/app/src/main/java/com/meloda/fast/adapter/UsersAdapterDeprecated.kt
@@ -9,12 +9,12 @@ import androidx.core.view.isVisible
import androidx.recyclerview.widget.DiffUtil
import com.meloda.fast.R
import com.meloda.fast.adapter.diffutil.UsersCallbackDeprecated
-import com.meloda.fast.api.model.VKUser
-import com.meloda.fast.api.util.VKUtil
import com.meloda.fast.base.BaseAdapter
import com.meloda.fast.base.BaseHolder
import com.meloda.fast.util.ImageUtils
import com.meloda.fast.widget.CircleImageView
+import com.meloda.vksdk.model.VKUser
+import com.meloda.vksdk.util.VKUtil
class UsersAdapterDeprecated(context: Context, values: ArrayList) :
BaseAdapter(context, values) {
@@ -41,25 +41,25 @@ class UsersAdapterDeprecated(context: Context, values: ArrayList) :
name.text = user.toString()
- val avatarPlaceholder = VKUtil.getAvatarPlaceholder(context, user.toString())
- avatar.setImageDrawable(avatarPlaceholder)
+// val avatarPlaceholder = VKUtil.getAvatarPlaceholder(context, user.toString())
+// avatar.setImageDrawable(avatarPlaceholder)
- ImageUtils.loadImage(user.photo200, avatar, avatarPlaceholder)
+// ImageUtils.loadImage(user.photo200, avatar, avatarPlaceholder)
online.isVisible = false
- VKUtil.getUserOnlineIcon(context, user)?.let {
- online.setImageDrawable(it)
- online.isVisible = true
- }
+// VKUtil.getUserOnlineIcon(context, user)?.let {
+// online.setImageDrawable(it)
+// online.isVisible = true
+// }
- onlineText.text = VKUtil.getUserOnline(user)
+// onlineText.text = VKUtil.getUserOnline(user)
//TODO: отладить открытие чата
}
}
- fun notifyChanges(oldList: List, newList: List = values) {
+ override fun notifyChanges(oldList: List, newList: List) {
val callback = UsersCallbackDeprecated(oldList, newList)
val diff = DiffUtil.calculateDiff(callback, false)
diff --git a/app/src/main/java/com/meloda/fast/adapter/diffutil/ConversationsCallback.kt b/app/src/main/java/com/meloda/fast/adapter/diffutil/ConversationsCallback.kt
new file mode 100644
index 00000000..6302806b
--- /dev/null
+++ b/app/src/main/java/com/meloda/fast/adapter/diffutil/ConversationsCallback.kt
@@ -0,0 +1,29 @@
+package com.meloda.fast.adapter.diffutil
+
+import androidx.recyclerview.widget.DiffUtil
+import com.meloda.vksdk.model.VKConversation
+
+class ConversationsCallback(
+ private val oldList: List,
+ private val newList: List
+) : DiffUtil.Callback() {
+
+ override fun getOldListSize() = oldList.size
+
+ override fun getNewListSize() = newList.size
+
+ override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
+ //TODO: rewrite
+ return false
+ }
+
+ override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
+ //TODO: rewrite
+ return false
+ }
+
+ override fun getChangePayload(oldItemPosition: Int, newItemPosition: Int): Any? {
+ //TODO: rewrite
+ return null
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/adapter/diffutil/ConversationsCallbackDeprecated.kt b/app/src/main/java/com/meloda/fast/adapter/diffutil/ConversationsCallbackDeprecated.kt
index ce72f25e..cb03d6cc 100644
--- a/app/src/main/java/com/meloda/fast/adapter/diffutil/ConversationsCallbackDeprecated.kt
+++ b/app/src/main/java/com/meloda/fast/adapter/diffutil/ConversationsCallbackDeprecated.kt
@@ -1,7 +1,7 @@
package com.meloda.fast.adapter.diffutil
import androidx.recyclerview.widget.DiffUtil
-import com.meloda.fast.api.model.VKConversation
+import com.meloda.vksdk.model.VKConversation
class ConversationsCallbackDeprecated(
private val oldList: List,
@@ -32,7 +32,7 @@ class ConversationsCallbackDeprecated(
val new = newList[newItemPosition]
if (true) return false
- return old.conversationId == new.conversationId
+ return old.id == new.id
}
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
@@ -53,8 +53,8 @@ class ConversationsCallbackDeprecated(
old.isDisabledForever == new.isDisabledForever &&
old.disabledUntil == new.disabledUntil &&
- old.inRead == new.inRead &&
- old.outRead == new.outRead &&
+ old.inReadMessageId == new.inReadMessageId &&
+ old.outReadMessageId == new.outReadMessageId &&
old.peerUser == new.peerUser &&
old.peerGroup == new.peerGroup &&
diff --git a/app/src/main/java/com/meloda/fast/adapter/diffutil/UsersCallbackDeprecated.kt b/app/src/main/java/com/meloda/fast/adapter/diffutil/UsersCallbackDeprecated.kt
index a8fd78fb..11878b0b 100644
--- a/app/src/main/java/com/meloda/fast/adapter/diffutil/UsersCallbackDeprecated.kt
+++ b/app/src/main/java/com/meloda/fast/adapter/diffutil/UsersCallbackDeprecated.kt
@@ -1,7 +1,7 @@
package com.meloda.fast.adapter.diffutil
import androidx.recyclerview.widget.DiffUtil
-import com.meloda.fast.api.model.VKUser
+import com.meloda.vksdk.model.VKUser
class UsersCallbackDeprecated(private val oldList: List, private val newList: List) :
DiffUtil.Callback() {
diff --git a/app/src/main/java/com/meloda/fast/api/VKApiKeys.kt b/app/src/main/java/com/meloda/fast/api/VKApiKeys.kt
deleted file mode 100644
index 96a59c27..00000000
--- a/app/src/main/java/com/meloda/fast/api/VKApiKeys.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.meloda.fast.api
-
-enum class VKApiKeys {
- READ_MESSAGE,
- RESTORE_MESSAGE,
- UPDATE_MESSAGE,
- NEW_MESSAGE,
- EDIT_MESSAGE,
- DELETE_MESSAGE,
- UPDATE_CONVERSATION,
-
- UPDATE_USER,
-
- UPDATE_GROUP
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/api/VKLongPollParser.kt b/app/src/main/java/com/meloda/fast/api/VKLongPollParser.kt
deleted file mode 100644
index b5ce125c..00000000
--- a/app/src/main/java/com/meloda/fast/api/VKLongPollParser.kt
+++ /dev/null
@@ -1,146 +0,0 @@
-package com.meloda.fast.api
-
-import android.util.Log
-import androidx.annotation.WorkerThread
-import com.meloda.fast.api.model.VKMessage
-import com.meloda.fast.api.util.VKUtil
-import com.meloda.fast.common.TaskManager
-import com.meloda.fast.database.MemoryCache
-import com.meloda.fast.event.EventInfo
-import org.json.JSONArray
-
-@Suppress("UNCHECKED_CAST")
-class VKLongPollParser {
-
- companion object {
-
- @WorkerThread
- fun parse(updates: JSONArray) {
- if (updates.length() == 0) {
- return
- }
-
- for (i in 0 until updates.length()) {
- val item = updates.optJSONArray(i)
- when (item.optInt(0)) {
- 2 -> messageSetFlags(item)
- 3 -> messageClearFlags(item)
- 4 -> messageEvent(item)
- 5 -> messageEdit(item)
- }
- }
- }
-
- private const val TAG = "VKLongPollParser"
-
- private fun messageEvent(item: JSONArray) {
- val message = VKUtil.parseLongPollMessage(item)
-
- TaskManager.execute {
- if (message.isFromUser()) {
- VKUtil.searchUser(message.fromId)?.let { message.fromUser = it }
- } else {
- VKUtil.searchGroup(message.fromId)?.let { message.fromGroup = it }
- }
-
- MemoryCache.getConversationById(message.peerId)?.let {
- it.lastMessage = message
- it.lastMessageId = message.messageId
-
- MemoryCache.put(it)
- }
-
- MemoryCache.put(message)
-
- val info = EventInfo(VKApiKeys.NEW_MESSAGE, message)
-
- sendEvent(info)
- }
- }
-
- private fun messageEdit(item: JSONArray) {
- val message = VKUtil.parseLongPollMessage(item)
- val info = EventInfo(VKApiKeys.EDIT_MESSAGE, message)
-
- MemoryCache.put(message)
-
- sendEvent(info)
- }
-
- private fun messageDelete(item: JSONArray) {
- val messageId = item.optInt(1)
- val peerId = item.optInt(3)
- val info = EventInfo(VKApiKeys.DELETE_MESSAGE, arrayOf(peerId, messageId))
-
- MemoryCache.deleteMessage(messageId)
-
- sendEvent(info)
- }
-
- private fun messageRestored(item: JSONArray) {
- val message = VKUtil.parseLongPollMessage(item)
- val info = EventInfo(VKApiKeys.RESTORE_MESSAGE, message)
-
- MemoryCache.put(message)
-
- sendEvent(info)
- }
-
- private fun messageRead(item: JSONArray) {
- val messageId = item.optInt(1)
- val peerId = item.optInt(3)
- val info = EventInfo(VKApiKeys.READ_MESSAGE, arrayOf(peerId, messageId))
-
- MemoryCache.edit(MemoryCache.getMessageById(messageId)?.apply { isRead = true })
-
- sendEvent(info)
- }
-
- private fun messageClearFlags(item: JSONArray) {
- val id = item.optInt(1)
- val flags = item.optInt(2)
- if (VKUtil.isMessageHasFlag(flags, "cancel_spam")) {
- Log.i(TAG, "Message with id $id: Not spam")
- }
- if (VKUtil.isMessageHasFlag(flags, "deleted")) {
- messageRestored(item)
- }
- if (VKUtil.isMessageHasFlag(flags, "important")) {
- Log.i(TAG, "Message with id $id: Not Important")
- }
- if (VKUtil.isMessageHasFlag(flags, "unread")) {
- messageRead(item)
- }
- }
-
- private fun messageSetFlags(item: JSONArray) {
- val id = item.optInt(1)
- val flags = item.optInt(2)
- if (VKUtil.isMessageHasFlag(flags, "delete_for_all")) {
- messageDelete(item)
- }
- if (VKUtil.isMessageHasFlag(flags, "deleted")) {
- messageDelete(item)
- }
- if (VKUtil.isMessageHasFlag(flags, "spam")) {
- Log.i(TAG, "Message with id $id: Spam")
- }
- if (VKUtil.isMessageHasFlag(flags, "important")) {
- Log.i(TAG, "Message with id $id: Important")
- }
- }
-
- private fun sendEvent(eventInfo: EventInfo<*>) {
- TaskManager.sendEvent(eventInfo)
- }
- }
-
- interface OnMessagesListener {
- fun onNewMessage(message: VKMessage)
- fun onEditMessage(message: VKMessage)
- fun onReadMessage(messageId: Int, peerId: Int)
- fun onDeleteMessage(messageId: Int, peerId: Int)
- fun onRestoredMessage(message: VKMessage)
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/api/model/VKAttachments.kt b/app/src/main/java/com/meloda/fast/api/model/VKAttachments.kt
deleted file mode 100644
index b4302d75..00000000
--- a/app/src/main/java/com/meloda/fast/api/model/VKAttachments.kt
+++ /dev/null
@@ -1,59 +0,0 @@
-package com.meloda.fast.api.model
-
-import org.json.JSONArray
-import java.util.*
-
-object VKAttachments {
-
- private const val TYPE_PHOTO = "photo"
- private const val TYPE_VIDEO = "video"
- private const val TYPE_AUDIO = "audio"
- private const val TYPE_DOC = "doc"
- private const val TYPE_LINK = "link"
- private const val TYPE_STICKER = "sticker"
- private const val TYPE_GIFT = "gift"
- private const val TYPE_AUDIO_MESSAGE = "audio_message"
- private const val TYPE_GRAFFITI = "graffiti"
- private const val TYPE_POLL = "poll"
- private const val TYPE_GEO = "geo"
- private const val TYPE_WALL = "wall"
- private const val TYPE_CALL = "call"
- private const val TYPE_STORY = "story"
- private const val TYPE_POINT = "point"
- private const val TYPE_MARKET = "market"
- private const val TYPE_ARTICLE = "article"
- private const val TYPE_PODCAST = "podcast"
- private const val TYPE_WALL_REPLY = "wall_reply"
- private const val TYPE_MONEY_REQUEST = "money_request"
- private const val TYPE_AUDIO_PLAYLIST = "audio_playlist"
-
- fun parse(array: JSONArray): ArrayList {
- val attachments = ArrayList(array.length())
-
- for (i in 0 until array.length()) {
- var attachment = array.optJSONObject(i) ?: continue
- if (attachment.has("attachment")) {
- attachment = attachment.optJSONObject("attachment") ?: continue
- }
-
- val type = attachment.optString("type")
- val jsonObject = attachment.optJSONObject(type) ?: continue
-
- when (type) {
- TYPE_PHOTO -> attachments.add(VKPhoto(jsonObject))
- TYPE_AUDIO -> attachments.add(VKAudio(jsonObject))
- TYPE_VIDEO -> attachments.add(VKVideo(jsonObject))
- TYPE_DOC -> attachments.add(VKDoc(jsonObject))
- TYPE_STICKER -> attachments.add(VKSticker(jsonObject))
- TYPE_LINK -> attachments.add(VKLink(jsonObject))
- TYPE_GIFT -> attachments.add(VKGift(jsonObject))
- TYPE_AUDIO_MESSAGE -> attachments.add(VKAudioMessage(jsonObject))
- TYPE_GRAFFITI -> attachments.add(VKGraffiti(jsonObject))
- TYPE_POLL -> attachments.add(VKPoll(jsonObject))
- TYPE_CALL -> attachments.add(VKCall(jsonObject))
- }
- }
-
- return attachments
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/api/model/VKAudio.kt b/app/src/main/java/com/meloda/fast/api/model/VKAudio.kt
deleted file mode 100644
index 918c1e67..00000000
--- a/app/src/main/java/com/meloda/fast/api/model/VKAudio.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.meloda.fast.api.model
-
-import org.json.JSONObject
-
-class VKAudio(o: JSONObject) : VKModel() {
-
- constructor() : this(JSONObject())
-
- var id = o.optInt("id", -1)
- var ownerId = o.optInt("owner_id", -1)
- var artist: String = o.optString("artist")
- var title: String = o.optString("title")
- var duration = o.optInt("duration")
- var url: String = o.optString("url")
- var date = o.optInt("date")
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/api/model/VKAudioMessage.kt b/app/src/main/java/com/meloda/fast/api/model/VKAudioMessage.kt
deleted file mode 100644
index f728aefd..00000000
--- a/app/src/main/java/com/meloda/fast/api/model/VKAudioMessage.kt
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.meloda.fast.api.model
-
-import org.json.JSONObject
-
-class VKAudioMessage(o: JSONObject) : VKModel() {
-
- constructor() : this(JSONObject())
-
- var duration = o.optInt("duration")
- var waveform = ArrayList()
- var linkOgg: String = o.optString("link_ogg")
- var linkMp3: String = o.optString("link_mp3")
-
- init {
- o.optJSONArray("waveform")?.let {
- val waveform = ArrayList()
- for (i in 0 until it.length()) {
- waveform.add(it.optInt(i))
- }
- this.waveform = waveform
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/api/model/VKCall.kt b/app/src/main/java/com/meloda/fast/api/model/VKCall.kt
deleted file mode 100644
index e2419fa1..00000000
--- a/app/src/main/java/com/meloda/fast/api/model/VKCall.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.meloda.fast.api.model
-
-import org.json.JSONObject
-
-class VKCall(o: JSONObject) : VKModel() {
-
- constructor() : this(JSONObject())
-
- var initiatorId = o.optInt("initiator_id", -1)
- var receiverId = o.optInt("receiver_id", -1)
- var state: String = o.optString("state") //reached, canceled_by_initiator, canceled_by_receiver
- var time = o.optInt("time")
- var duration = o.optInt("duration")
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/api/model/VKComment.kt b/app/src/main/java/com/meloda/fast/api/model/VKComment.kt
deleted file mode 100644
index 3e055614..00000000
--- a/app/src/main/java/com/meloda/fast/api/model/VKComment.kt
+++ /dev/null
@@ -1,4 +0,0 @@
-package com.meloda.fast.api.model
-
-class VKComment { //https://vk.com/dev/objects/comment
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/api/model/VKConversation.kt b/app/src/main/java/com/meloda/fast/api/model/VKConversation.kt
deleted file mode 100644
index 857e2cd0..00000000
--- a/app/src/main/java/com/meloda/fast/api/model/VKConversation.kt
+++ /dev/null
@@ -1,144 +0,0 @@
-package com.meloda.fast.api.model
-
-import androidx.room.Embedded
-import androidx.room.Entity
-import androidx.room.PrimaryKey
-import androidx.room.RoomWarnings
-import org.json.JSONObject
-
-@SuppressWarnings(RoomWarnings.PRIMARY_KEY_FROM_EMBEDDED_IS_DROPPED)
-@Entity(tableName = "conversations")
-class VKConversation() : VKModel(), Cloneable {
-
- companion object {
- var profiles = arrayListOf()
- var groups = arrayListOf()
-
- var conversationsCount: Int = 0
-
- const val STATE_IN = "in"
- const val STATE_KICKED = "kicked"
- const val STATE_LEFT = "left"
-
- const val TYPE_USER = "user"
- const val TYPE_CHAT = "chat"
- const val TYPE_GROUP = "group"
-
- var count = 0
- }
-
- /*
- 18 — пользователь заблокирован или удален;
- 900 — нельзя отправить сообщение пользователю, который в чёрном списке;
- 901 — пользователь запретил сообщения от сообщества;
- 902 — пользователь запретил присылать ему сообщения с помощью настроек приватности;
- 915 — в сообществе отключены сообщения;
- 916 — в сообществе заблокированы сообщения;
- 917 — нет доступа к чату;
- 918 — нет доступа к e-mail;
- 203 — нет доступа к сообществу
- */
-
- var isAllowed = false
- var reason = -1
-
- var inRead = 0
- var outRead = 0
- var lastMessageId = 0
- var unreadCount = 0
-
- @PrimaryKey(autoGenerate = false)
- var conversationId = 0
-
- var type: String = ""
- var localId = 0
-
- var disabledUntil = 0
- var isDisabledForever = false
- var isNoSound = false
-
- var membersCount = 0
- var title: String = ""
-
- var pinnedMessageId = 0
-
- var state: String = ""
-
- @Embedded(prefix = "cMessage")
- var lastMessage = VKMessage()
-
- var isGroupChannel = false
-
- var photo50: String = ""
- var photo100: String = ""
- var photo200: String = ""
-
- @Embedded(prefix = "cUser")
- var peerUser: VKUser? = null
-
- @Embedded(prefix = "cGroup")
- var peerGroup: VKGroup? = null
-
- constructor(o: JSONObject) : this() {
- inRead = o.optInt("in_read")
- outRead = o.optInt("out_read")
- lastMessageId = o.optInt("last_message_id", -1)
- unreadCount = o.optInt("unread_count", 0)
-
- o.optJSONObject("peer")?.let {
- conversationId = it.optInt("id", -1)
- type = it.optString("type")
- localId = it.optInt("local_id")
- }
-
- o.optJSONObject("push_settings")?.let {
- disabledUntil = it.optInt("disabled_until")
- isDisabledForever = it.optBoolean("disabled_forever")
- isNoSound = it.optBoolean("no_sound")
- }
-
- o.optJSONObject("can_write")?.let {
- isAllowed = it.optBoolean("allowed")
- reason = it.optInt("reason", -1)
- }
-
- o.optJSONObject("chat_settings")?.let {
- membersCount = it.optInt("members_count")
- title = it.optString("title")
-
- it.optJSONObject("pinned_message")?.let { pinned ->
- pinnedMessageId = VKPinnedMessage(pinned).id
- }
-
- state = it.optString("state")
-
- it.optJSONObject("photo")?.let { photo ->
- photo50 = photo.optString("photo_50")
- photo100 = photo.optString("photo_100")
- photo200 = photo.optString("photo_200")
- }
-
- isGroupChannel = it.optBoolean("is_group_channel")
- }
- }
-
- fun isNotificationsDisabled() = (isDisabledForever || disabledUntil > 0 || isNoSound)
-
- fun isChatId() = conversationId > 2_000_000_000
-
- fun isChat() = type == TYPE_CHAT
-
- fun isUser() = type == TYPE_USER
-
- fun isNotUser() = !isUser()
-
- fun isGroup() = type == TYPE_GROUP
-
- override fun toString(): String {
- return title
- }
-
- public override fun clone(): VKConversation {
- return super.clone() as VKConversation
- }
-}
diff --git a/app/src/main/java/com/meloda/fast/api/model/VKDoc.kt b/app/src/main/java/com/meloda/fast/api/model/VKDoc.kt
deleted file mode 100644
index 223e363a..00000000
--- a/app/src/main/java/com/meloda/fast/api/model/VKDoc.kt
+++ /dev/null
@@ -1,73 +0,0 @@
-package com.meloda.fast.api.model
-
-import org.json.JSONObject
-import java.util.*
-
-class VKDoc(o: JSONObject) : VKModel() {
-
- constructor() : this(JSONObject())
-
- companion object {
- const val TYPE_NONE = 0
- const val TYPE_TEXT = 1
- const val TYPE_ARCHIVE = 2
- const val TYPE_GIF = 3
- const val TYPE_IMAGE = 4
- const val TYPE_AUDIO = 5
- const val TYPE_VIDEO = 6
- const val TYPE_BOOK = 7
- const val TYPE_UNKNOWN = 8
- }
-
- var id = o.optInt("id", -1)
- var ownerId = o.optInt("owner_id", -1)
- var title: String = o.optString("title")
- var size = o.optInt("size")
- var ext: String = o.optString("ext")
- var url: String = o.optString("url")
- var date = o.optInt("date")
- var type = o.optInt("type")
- var preview: Preview? = null
-
- init {
- o.optJSONObject("preview")?.let {
- preview = Preview(it)
- }
- }
-
- class Preview(o: JSONObject) {
- var photo: Photo? = null
- var graffiti: Graffiti? = null
-
- inner class Photo(o: JSONObject) {
- var sizes: ArrayList? = null
-
- init {
- o.optJSONArray("sizes")?.let {
- val sizes = ArrayList()
- for (i in 0 until it.length()) {
- sizes.add(VKPhotoSize(it.optJSONObject(i)))
- }
- this.sizes = sizes
- }
- }
- }
-
- class Graffiti(o: JSONObject) {
- var src: String = o.optString("src")
- var width = o.optInt("width")
- var height = o.optInt("height")
- }
-
- init {
- o.optJSONObject("photo")?.let {
- photo = Photo(it)
- }
-
- o.optJSONObject("graffiti")?.let {
- graffiti = Graffiti(it)
- }
-
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/api/model/VKFriend.kt b/app/src/main/java/com/meloda/fast/api/model/VKFriend.kt
deleted file mode 100644
index 4cc370c5..00000000
--- a/app/src/main/java/com/meloda/fast/api/model/VKFriend.kt
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.meloda.fast.api.model
-
-import androidx.room.Entity
-import androidx.room.PrimaryKey
-
-@Entity(tableName = "friends")
-class VKFriend() {
-
- @PrimaryKey(autoGenerate = false)
- var friendId: Int = -1
-
- var userId: Int = -1
-
- constructor(friendId: Int, userId: Int) : this() {
- this.friendId = friendId
- this.userId = userId
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/api/model/VKGift.kt b/app/src/main/java/com/meloda/fast/api/model/VKGift.kt
deleted file mode 100644
index cc89fba8..00000000
--- a/app/src/main/java/com/meloda/fast/api/model/VKGift.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.meloda.fast.api.model
-
-import org.json.JSONObject
-
-class VKGift(o: JSONObject) : VKModel() {
-
- constructor() : this(JSONObject())
-
- var id = o.optInt("id", -1)
- var thumb256: String = o.optString("thumb_256")
- var thumb96: String = o.optString("thumb_96")
- var thumb48: String = o.optString("thumb_48")
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/api/model/VKGraffiti.kt b/app/src/main/java/com/meloda/fast/api/model/VKGraffiti.kt
deleted file mode 100644
index ef97619c..00000000
--- a/app/src/main/java/com/meloda/fast/api/model/VKGraffiti.kt
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.meloda.fast.api.model
-
-import org.json.JSONObject
-
-class VKGraffiti(o: JSONObject) : VKModel() {
-
- constructor() : this(JSONObject())
-
- var id = o.optInt("id", -1)
- var ownerId = o.optInt("owner_id", -1)
- var url: String = o.optString("url")
- var width = o.optInt("width")
- var height = o.optInt("height")
- var accessKey: String = o.optString("access_key")
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/api/model/VKGroup.kt b/app/src/main/java/com/meloda/fast/api/model/VKGroup.kt
deleted file mode 100644
index d80774e5..00000000
--- a/app/src/main/java/com/meloda/fast/api/model/VKGroup.kt
+++ /dev/null
@@ -1,46 +0,0 @@
-package com.meloda.fast.api.model
-
-import androidx.room.Entity
-import androidx.room.PrimaryKey
-import org.json.JSONArray
-import org.json.JSONObject
-
-@Entity(tableName = "groups")
-open class VKGroup(o: JSONObject) : VKModel() {
-
- constructor() : this(JSONObject())
-
- companion object {
- const val DEFAULT_FIELDS = "description,members_count,counters,status,verified"
-
- fun isGroupId(id: Int): Boolean {
- return id < 0
- }
-
- val EMPTY: VKGroup = object : VKGroup() {
- init {
- name = "Unknown"
- }
- }
-
- fun parse(array: JSONArray): ArrayList {
- val groups = ArrayList()
-
- for (i in 0 until array.length()) {
- groups.add(VKGroup(array.optJSONObject(i)))
- }
- return groups
- }
- }
-
- @PrimaryKey(autoGenerate = false)
- var groupId = o.optInt("id", -1)
- var name: String = o.optString("name")
- var screenName: String = o.optString("screen_name")
- var isClosed = o.optInt("is_closed") == 1
- var deactivated: String = o.optString("deactivated")
- var type: String = o.optString("type")
- var photo50: String = o.optString("photo_50")
- var photo100: String = o.optString("photo_100")
- var photo200: String = o.optString("photo_200")
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/api/model/VKLongPollServer.kt b/app/src/main/java/com/meloda/fast/api/model/VKLongPollServer.kt
deleted file mode 100644
index 8eb3f741..00000000
--- a/app/src/main/java/com/meloda/fast/api/model/VKLongPollServer.kt
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.meloda.fast.api.model
-
-import org.json.JSONObject
-
-class VKLongPollServer(o: JSONObject) : VKModel() {
-
- constructor() : this(JSONObject())
-
- var key: String = o.optString("key")
- var server = o.optString("server").replace("\\", "")
- var ts: Long = o.optLong("ts")
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/api/model/VKMarketAlbum.kt b/app/src/main/java/com/meloda/fast/api/model/VKMarketAlbum.kt
deleted file mode 100644
index 041d1a04..00000000
--- a/app/src/main/java/com/meloda/fast/api/model/VKMarketAlbum.kt
+++ /dev/null
@@ -1,4 +0,0 @@
-package com.meloda.fast.api.model
-
-class VKMarketAlbum { //https://vk.com/dev/objects/market_album
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/api/model/VKMarketItem.kt b/app/src/main/java/com/meloda/fast/api/model/VKMarketItem.kt
deleted file mode 100644
index e9a1d6b2..00000000
--- a/app/src/main/java/com/meloda/fast/api/model/VKMarketItem.kt
+++ /dev/null
@@ -1,4 +0,0 @@
-package com.meloda.fast.api.model
-
-class VKMarketItem { //https://vk.com/dev/objects/market_item
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/api/model/VKMessageAction.kt b/app/src/main/java/com/meloda/fast/api/model/VKMessageAction.kt
deleted file mode 100644
index 08572edb..00000000
--- a/app/src/main/java/com/meloda/fast/api/model/VKMessageAction.kt
+++ /dev/null
@@ -1,57 +0,0 @@
-package com.meloda.fast.api.model
-
-import androidx.room.Ignore
-import org.json.JSONObject
-
-class VKMessageAction() : VKModel() {
-
- companion object {
- const val ACTION_CHAT_CREATE = "chat_create"
- const val ACTION_PHOTO_UPDATE = "chat_photo_update"
- const val ACTION_PHOTO_REMOVE = "chat_photo_remove"
- const val ACTION_TITLE_UPDATE = "chat_title_update"
- const val ACTION_PIN_MESSAGE = "chat_pin_message"
- const val ACTION_UNPIN_MESSAGE = "chat_unpin_message"
- const val ACTION_INVITE_USER = "chat_invite_user"
- const val ACTION_INVITE_USER_BY_LINK = "chat_invite_user_by_link"
- const val ACTION_KICK_USER = "chat_kick_user"
- const val ACTION_SCREENSHOT = "chat_screenshot"
- const val ACTION_INVITE_USER_BY_CALL = "chat_invite_user_by_call"
- const val ACTION_INVITE_USER_BY_CALL_JOIN_LINK = "chat_invite_user_by_call_link"
- }
-
- /*
- chat_photo_update — обновлена фотография беседы;
- chat_photo_remove — удалена фотография беседы;
- chat_create — создана беседа;
- chat_title_update — обновлено название беседы;
- chat_invite_user — приглашен пользователь;
- chat_kick_user — исключен пользователь;
- chat_pin_message — закреплено сообщение;
- chat_unpin_message — откреплено сообщение;
- chat_invite_user_by_link — пользователь присоединился к беседе по ссылке.
- */
-
- var type: String = ""
-
- var memberId = 0
-
- @Ignore
- var message: VKMessage? = null
-
- var conversationMessageId = 0
-
- var text: String = ""
- var oldText: String = ""
-
-// @Embedded(prefix = "photo")
-// var photo: Photo? = null
-
- //TODO: add photo
-
- constructor(o: JSONObject) : this() {
- type = o.optString("type")
- memberId = o.optInt("member_id", -1)
- text = o.optString("text")
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/api/model/VKPhoto.kt b/app/src/main/java/com/meloda/fast/api/model/VKPhoto.kt
deleted file mode 100644
index 4b763686..00000000
--- a/app/src/main/java/com/meloda/fast/api/model/VKPhoto.kt
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.meloda.fast.api.model
-
-import org.json.JSONObject
-import java.util.*
-
-class VKPhoto(o: JSONObject) : VKModel() {
-
- constructor() : this(JSONObject())
-
- var id = o.optInt("id", -1)
- var albumId = o.optInt("album_id", -1)
- var ownerId = o.optInt("owner_id", -1)
- var text: String = o.optString("text")
- var date = o.optInt("date")
- var width = o.optInt("width")
- var height = o.optInt("height")
- var sizes: ArrayList? = null
-
- init {
- o.optJSONArray("sizes")?.let {
- val sizes = ArrayList()
- for (i in 0 until it.length()) {
- sizes.add(VKPhotoSize(it.optJSONObject(i)))
- }
- this.sizes = sizes
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/api/model/VKPhotoSize.kt b/app/src/main/java/com/meloda/fast/api/model/VKPhotoSize.kt
deleted file mode 100644
index 2a3b1a23..00000000
--- a/app/src/main/java/com/meloda/fast/api/model/VKPhotoSize.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.meloda.fast.api.model
-
-import org.json.JSONObject
-
-class VKPhotoSize(o: JSONObject) : VKModel() {
-
- constructor() : this(JSONObject())
-
- var type: String = o.optString("type")
- var url: String = o.optString("url")
- var height = o.optInt("height")
- var width = o.optInt("width")
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/api/model/VKPinnedMessage.kt b/app/src/main/java/com/meloda/fast/api/model/VKPinnedMessage.kt
deleted file mode 100644
index 13d84bc7..00000000
--- a/app/src/main/java/com/meloda/fast/api/model/VKPinnedMessage.kt
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.meloda.fast.api.model
-
-import org.json.JSONObject
-import java.util.*
-
-class VKPinnedMessage(o: JSONObject) : VKModel() {
-
- constructor() : this(JSONObject())
-
- var id = o.optInt("id", -1)
- var date = o.optInt("date")
- var fromId = o.optInt("from_id", -1)
- var text: String = o.optString("text")
- var attachments: ArrayList? = null
- var fwdMessages: ArrayList? = null
-
- init {
- o.optJSONArray("attachments")?.let {
- attachments = VKAttachments.parse(it)
- }
-
- //TODO: parse forwarded
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/api/model/VKPoll.kt b/app/src/main/java/com/meloda/fast/api/model/VKPoll.kt
deleted file mode 100644
index 161c4471..00000000
--- a/app/src/main/java/com/meloda/fast/api/model/VKPoll.kt
+++ /dev/null
@@ -1,55 +0,0 @@
-package com.meloda.fast.api.model
-
-import android.graphics.Color
-import org.json.JSONObject
-import java.io.Serializable
-import java.util.*
-
-class VKPoll(o: JSONObject) : VKModel() {
-
- constructor() : this(JSONObject())
-
- var id = o.optInt("id", -1)
- var ownerId = o.optInt("owner_id", -1)
- var created = o.optInt("created")
- var question: String = o.optString("question")
- var votes = o.optInt("votes")
- var answers = ArrayList()
- var isAnonymous = o.optBoolean("anonymous")
- var isMultiple = o.optBoolean("multiple")
- var answerIds = ArrayList()
- var endDate = o.optInt("end_date")
- var isClosed = o.optBoolean("closed")
- var isBoard = o.optBoolean("is_board")
- var isCanEdit = o.optBoolean("can_edit")
- var isCanVote = false
- var isCanReport = false
- var isCanShare = false
- var authorId = 0
- var background = Color.WHITE
-
- //TODO: private ArrayList friends
-
- init {
- o.optJSONArray("answers")?.let {
- val answers = ArrayList()
- for (i in 0 until it.length()) {
- answers.add(Answer(it.optJSONObject(i)))
- }
- this.answers = answers
- }
-
- //setAnswerIds();
-
- // ...
- }
-
- class Answer(o: JSONObject) : Serializable {
-
- var id = o.optInt("id", -1)
- var text: String = o.optString("text")
- var votes = o.optInt("votes")
- var rate = o.optInt("rate")
-
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/api/model/VKSticker.kt b/app/src/main/java/com/meloda/fast/api/model/VKSticker.kt
deleted file mode 100644
index 9e4303c9..00000000
--- a/app/src/main/java/com/meloda/fast/api/model/VKSticker.kt
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.meloda.fast.api.model
-
-import org.json.JSONObject
-import java.util.*
-
-class VKSticker(o: JSONObject) : VKModel() {
-
- constructor() : this(JSONObject())
-
- var productId = o.optInt("product_id", -1)
- var stickerId = o.optInt("sticker_id", -1)
- var images: ArrayList? = null
-
- init {
- o.optJSONArray("images")?.let {
- val images = ArrayList()
- for (i in 0 until it.length()) {
- images.add(Image(it.optJSONObject(i)))
- }
- this.images = images
- }
- }
-
- class Image(o: JSONObject) : VKModel() {
-
- var url: String = o.optString("url")
- var width = o.optInt("width")
- var height = o.optInt("height")
-
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/api/model/VKUser.kt b/app/src/main/java/com/meloda/fast/api/model/VKUser.kt
deleted file mode 100644
index 57157291..00000000
--- a/app/src/main/java/com/meloda/fast/api/model/VKUser.kt
+++ /dev/null
@@ -1,74 +0,0 @@
-package com.meloda.fast.api.model
-
-import androidx.room.Entity
-import androidx.room.PrimaryKey
-import org.json.JSONArray
-import org.json.JSONObject
-
-@Entity(tableName = "users")
-open class VKUser(o: JSONObject) : VKModel() {
-
- constructor() : this(JSONObject())
-
- companion object {
-
- var friendsCount: Int = 0
-
- const val DEFAULT_FIELDS =
- "photo_50,photo_100,photo_200,status,screen_name,online,online_mobile,last_seen,verified,sex"
-
- val EMPTY: VKUser = object : VKUser() {
- override fun toString(): String {
- return "Unknown Unknown"
- }
- }
-
- fun isUserId(id: Int): Boolean {
- return id > 0 && id < 2000000000
- }
-
-
- @JvmStatic
- fun parse(array: JSONArray): ArrayList {
- val users = ArrayList()
-
- for (i in 0 until array.length()) {
- users.add(VKUser(array.optJSONObject(i)))
- }
-
- return users
- }
- }
-
- @PrimaryKey(autoGenerate = false)
- var userId = o.optInt("id", -1)
- var firstName: String = o.optString("first_name")
- var lastName: String = o.optString("last_name")
- var deactivated: String = o.optString("deactivated")
- var isClosed = o.optBoolean("is_closed")
- var isCanAccessClosed = o.optBoolean("can_access_closed")
- var sex = o.optInt("sex")
- var screenName: String = o.optString("screen_name")
- var photo50: String = o.optString("photo_50")
- var photo100: String = o.optString("photo_100")
- var photo200: String = o.optString("photo_200")
- var isOnline = o.optInt("online") == 1
- var isOnlineMobile = isOnline && o.optInt("online_mobile") == 1
- var status: String = o.optString("status")
-
- var lastSeen = 0
- var lastSeenPlatform = 0
-
- var isVerified = o.optInt("verified") == 1
-
- init {
- o.optJSONObject("last_seen")?.let {
- lastSeen = it.optInt("time")
- lastSeenPlatform = it.optInt("platform")
- }
- }
-
- override fun toString(): String {
- return "$firstName $lastName"
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/api/model/VKVideo.kt b/app/src/main/java/com/meloda/fast/api/model/VKVideo.kt
deleted file mode 100644
index 3b48c79c..00000000
--- a/app/src/main/java/com/meloda/fast/api/model/VKVideo.kt
+++ /dev/null
@@ -1,37 +0,0 @@
-package com.meloda.fast.api.model
-
-import org.json.JSONObject
-
-class VKVideo(o: JSONObject) : VKModel() {
-
- constructor() : this(JSONObject())
-
- var id = o.optInt("id", -1)
- var ownerId = o.optInt("owner_id", -1)
- var title: String = o.optString("title")
- var description: String = o.optString("description")
- var duration = o.optInt("duration", -1)
- var photo130: String = o.optString("photo_130")
- var photo320: String = o.optString("photo_320")
- var photo640: String = o.optString("photo_640")
- var photo800: String = o.optString("photo_800")
- var photo1280: String = o.optString("photo_1280")
- var firstFrame130: String = o.optString("first_frame_130")
- var firstFrame320: String = o.optString("first_frame_320")
- var firstFrame640: String = o.optString("first_frame_640")
- var firstFrame800: String = o.optString("first_frame_800")
- var firstFrame1280: String = o.optString("first_frame_1280")
- var date = o.optInt("date")
- var views = o.optInt("views")
- var comments = o.optInt("comments")
- var player: String = o.optString("player")
- var isCanEdit = o.optInt("can_edit", 0) == 1
- var isCanAdd = o.optInt("can_add") == 1
- var isPrivate = o.optInt("is_private", 0) == 1
- var accessKey: String = o.optString("access_key")
- var isProcessing = o.optInt("processing", 0) == 1
- var isLive = o.optInt("live", 0) == 1
- var isUpcoming = o.optInt("upcoming", 0) == 1
- var isFavorite = o.optBoolean("favorite")
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/api/model/VKWall.kt b/app/src/main/java/com/meloda/fast/api/model/VKWall.kt
deleted file mode 100644
index e05ab473..00000000
--- a/app/src/main/java/com/meloda/fast/api/model/VKWall.kt
+++ /dev/null
@@ -1,4 +0,0 @@
-package com.meloda.fast.api.model
-
-class VKWall { //https://vk.com/dev/objects/post
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/api/util/VKUtil.kt b/app/src/main/java/com/meloda/fast/api/util/VKUtil.kt
deleted file mode 100644
index 637c2a0b..00000000
--- a/app/src/main/java/com/meloda/fast/api/util/VKUtil.kt
+++ /dev/null
@@ -1,718 +0,0 @@
-package com.meloda.fast.api.util
-
-import android.content.Context
-import android.graphics.drawable.Drawable
-import android.util.Log
-import androidx.annotation.WorkerThread
-import androidx.core.content.ContextCompat
-import com.amulyakhare.textdrawable.TextDrawable
-import com.meloda.fast.BuildConfig
-import com.meloda.fast.R
-import com.meloda.fast.api.UserConfig
-import com.meloda.fast.api.VKApiKeys
-import com.meloda.fast.api.model.*
-import com.meloda.fast.common.AppGlobal
-import com.meloda.fast.common.TaskManager
-import com.meloda.fast.database.MemoryCache
-import com.meloda.fast.extensions.ContextExtensions.color
-import com.meloda.fast.extensions.ContextExtensions.drawable
-import com.meloda.fast.extensions.StringExtensions.lowerCase
-import com.meloda.fast.listener.OnResponseListener
-import com.meloda.fast.util.TextUtils
-import org.json.JSONArray
-import java.text.SimpleDateFormat
-import java.util.*
-import java.util.regex.Pattern
-import kotlin.math.abs
-
-object VKUtil {
-
- private const val TAG = "VKM: VKUtil"
-
- fun extractPattern(string: String, pattern: String): String? {
- val p = Pattern.compile(pattern)
- val m = p.matcher(string)
- return if (!m.find()) null else m.toMatchResult().group(1)
- }
-
- private const val pattern_string_profile_id = "^(id)?(\\d{1,10})$"
-
- private val pattern_profile_id = Pattern.compile(pattern_string_profile_id)
-
- fun parseProfileId(text: String): String? {
- val m = pattern_profile_id.matcher(text)
- return if (!m.find()) null else m.group(2)
- }
-
- fun sortMessagesByDate(
- values: ArrayList,
- firstOnTop: Boolean
- ): ArrayList {
- values.sortWith { m1, m2 ->
- val d1 = m1.date
- val d2 = m2.date
-
- if (firstOnTop) {
- d2 - d1
- } else {
- d1 - d2
- }
- }
-
- return values
- }
-
- fun sortConversationsByDate(
- values: ArrayList,
- firstOnTop: Boolean
- ): ArrayList {
- values.sortWith { c1, c2 ->
- val d1 = c1.lastMessage.date
- val d2 = c2.lastMessage.date
-
- return@sortWith if (firstOnTop) {
- d2 - d1
- } else {
- d1 - d2
- }
- }
-
- return values
- }
-
- fun prepareMessageText(message: String): String {
- if (message.isEmpty()) return message
-
- var newText = message
-
- val mentions = hashMapOf()
-
- var startFrom = 0
-
- while (true) {
- val leftBracketIndex = newText.indexOf('[', startFrom)
- val verticalLineIndex = newText.indexOf('|', startFrom)
- val rightBracketIndex = newText.indexOf(']', startFrom)
-
- if (leftBracketIndex == -1 ||
- verticalLineIndex == -1 ||
- rightBracketIndex == -1
- ) {
- break
- }
-
- val id = newText.substring(leftBracketIndex + 1, verticalLineIndex)
-
- if (!id.matches(Regex("^id(\\d+)\$")) || rightBracketIndex - verticalLineIndex < 2) {
- break
- }
-
- val text = newText.substring(verticalLineIndex + 1, rightBracketIndex)
-
- val str = "[$id|$text]"
-
- mentions[str] = text
- startFrom = rightBracketIndex + 1
- }
-
- mentions.forEach {
- newText = newText.replace(it.key, it.value)
- }
-
- return newText
- }
-
-// fun removeTime(date: Date): Long {
-// return Calendar.getInstance().apply {
-// time = date
-// this[Calendar.HOUR_OF_DAY] = 0
-// this[Calendar.MINUTE] = 0
-// this[Calendar.SECOND] = 0
-// this[Calendar.MILLISECOND] = 0
-// }.timeInMillis
-// }
-
- fun getUserOnline(user: VKUser): String {
- val r = AppGlobal.resources
- return if (user.isOnline) {
- if (user.isOnlineMobile) {
- r.getString(R.string.user_online_mobile)
- } else {
- r.getString(R.string.user_online)
- }
- } else {
- if (user.lastSeen == 0) {
- r.getString(R.string.user_last_seen_recently)
- } else {
- r.getString(R.string.user_last_seen_at, getLastSeenTime(user.lastSeen * 1000L))
- }
- }
- }
-
- fun getUserOnlineIcon(
- context: Context,
- conversation: VKConversation?,
- peerUser: VKUser?
- ): Drawable? {
- return if (conversation != null) {
- if (conversation.isUser() && peerUser != null) {
- if (!peerUser.isOnline) {
- null
- } else {
- ContextCompat.getDrawable(
- context,
- if (peerUser.isOnlineMobile) R.drawable.ic_online_mobile else R.drawable.ic_online_pc
- )
- }
- } else null
- } else {
- if (peerUser!!.isOnline) {
- ContextCompat.getDrawable(
- context,
- if (peerUser.isOnlineMobile) R.drawable.ic_online_mobile else R.drawable.ic_online_pc
- )
- } else {
- null
- }
- }
- }
-
- fun getUserOnlineIcon(context: Context, user: VKUser): Drawable? {
- return getUserOnlineIcon(context, null, user)
- }
-
- //TODO: нормальное время
- fun getLastSeenTime(date: Long): String {
- return SimpleDateFormat("HH:mm", Locale.getDefault()).format(date)
- }
-
- fun getAvatarPlaceholder(context: Context, dialogTitle: String): TextDrawable {
- return TextDrawable.builder().buildRound(
- if (dialogTitle.isEmpty()) "" else {
- TextUtils.getFirstLetterFromString(dialogTitle)
- },
- context.color(R.color.accent)
- )
- }
-
- @WorkerThread
- fun searchUser(id: Int, onResponseListener: OnResponseListener? = null): VKUser? {
- return if (VKGroup.isGroupId(id) || isChatId(id)) {
- null
- } else {
- MemoryCache.getUserById(id)?.let { return it }
-
- if (BuildConfig.DEBUG) {
- Log.d(TAG, "User with id $id not found")
- }
-
- TaskManager.loadUser(VKApiKeys.UPDATE_USER, id, onResponseListener)
-
- return null
- }
- }
-
- @WorkerThread
- fun searchGroup(id: Int, onResponseListener: OnResponseListener? = null): VKGroup? {
- return if (!VKGroup.isGroupId(id) || isChatId(id)) {
- null
- } else {
- MemoryCache.getGroupById(abs(id))?.let { return it }
-
- if (BuildConfig.DEBUG) {
- Log.d(TAG, "Group with id $id not found")
- }
-
- TaskManager.loadGroup(VKApiKeys.UPDATE_GROUP, abs(id), onResponseListener)
-
- return null
- }
- }
-
- fun getTitle(conversation: VKConversation, peerUser: VKUser?, peerGroup: VKGroup?): String {
- return when {
- conversation.isUser() -> {
- peerUser?.let { return it.toString() } ?: ""
- }
-
- conversation.isGroup() -> {
- peerGroup?.let { return it.name } ?: ""
- }
-
- conversation.isChat() -> {
- conversation.title
- }
-
- else -> ""
- }
- }
-
- fun getMessageTitle(message: VKMessage, fromUser: VKUser?, fromGroup: VKGroup?): String {
- return when {
- message.isFromUser() -> {
- fromUser?.let { return it.toString() } ?: ""
- }
-
- message.isFromGroup() -> {
- fromGroup?.let { return it.name } ?: ""
- }
-
- else -> ""
- }
- }
-
- fun getAvatar(conversation: VKConversation, peerUser: VKUser?, peerGroup: VKGroup?): String {
- return when {
- conversation.isUser() -> {
- peerUser?.let { return it.photo200 } ?: ""
- }
-
- conversation.isGroup() -> {
- peerGroup?.let { return it.photo200 } ?: ""
- }
-
- conversation.isChat() -> {
- conversation.photo200
- }
-
- else -> ""
- }
- }
-
- fun getUserAvatar(message: VKMessage, fromUser: VKUser?, fromGroup: VKGroup?): String {
- return when {
- message.isFromUser() -> {
- fromUser?.let { return it.photo100 } ?: ""
- }
-
- message.isFromGroup() -> {
- fromGroup?.let { return it.photo100 } ?: ""
- }
-
- else -> ""
- }
- }
-
- fun getUserPhoto(user: VKUser): String {
- if (user.photo200.isEmpty()) {
- if (user.photo100.isEmpty()) {
- if (user.photo50.isEmpty()) {
- return ""
- }
- } else {
- return user.photo100
- }
- } else {
- return user.photo200
- }
-
- return ""
- }
-
- fun getGroupPhoto(group: VKGroup): String {
- if (group.photo200.isEmpty()) {
- if (group.photo100.isEmpty()) {
- if (group.photo50.isEmpty()) {
- return ""
- }
- } else {
- return group.photo100
- }
- } else {
- return group.photo200
- }
-
- return ""
- }
-
- fun getDialogType(context: Context, conversation: VKConversation): Drawable? {
- return when {
- conversation.isGroupChannel -> {
- ContextCompat.getDrawable(context, R.drawable.ic_dialog_type_channel)
- }
- conversation.isChat() -> {
- ContextCompat.getDrawable(context, R.drawable.ic_dialog_type_conversation)
- }
- else -> null
- }
- }
-
- fun getAttachmentText(context: Context, attachments: List): String {
- val resId: Int
-
- if (attachments.isNotEmpty()) {
- if (attachments.size > 1) {
- var oneType = true
- val className = attachments[0].javaClass.simpleName
-
- for (model in attachments) {
- if (model.javaClass.simpleName != className) {
- oneType = false
- break
- }
- }
-
- return if (oneType) {
- val objectClass: Class = attachments[0].javaClass
- resId = when (objectClass) {
- VKPhoto::class.java -> {
- R.string.message_attachment_photos
- }
- VKVideo::class.java -> {
- R.string.message_attachment_videos
- }
- VKAudio::class.java -> {
- R.string.message_attachment_audios
- }
- VKDoc::class.java -> {
- R.string.message_attachment_docs
- }
- else -> {
- -1
- }
- }
- if (resId == -1) "Unknown attachments" else context.getString(
- resId,
- attachments.size
- ).toLowerCase(Locale.getDefault())
- } else {
- context.getString(R.string.message_attachments_many)
- }
- } else {
- val objectClass: Class = attachments[0].javaClass
-
- resId = when (objectClass) {
- VKPhoto::class.java -> {
- R.string.message_attachment_photo
- }
- VKAudio::class.java -> {
- R.string.message_attachment_audio
- }
- VKVideo::class.java -> {
- R.string.message_attachment_video
- }
- VKDoc::class.java -> {
- R.string.message_attachment_doc
- }
- VKGraffiti::class.java -> {
- R.string.message_attachment_graffiti
- }
- VKAudioMessage::class.java -> {
- R.string.message_attachment_voice
- }
- VKSticker::class.java -> {
- R.string.message_attachment_sticker
- }
- VKGift::class.java -> {
- R.string.message_attachment_gift
- }
- VKLink::class.java -> {
- R.string.message_attachment_link
- }
- VKPoll::class.java -> {
- R.string.message_attachment_poll
- }
- VKCall::class.java -> {
- R.string.message_attachment_call
- }
- else -> {
- return "Unknown"
- }
- }
- }
- } else {
- return ""
- }
- return context.getString(resId)
- }
-
- fun getAttachmentDrawable(context: Context, attachments: List): Drawable? {
- if (attachments.isEmpty() || attachments.size > 1) return null
-
- var resId = -1
-
- when (attachments[0].javaClass) {
- VKPhoto::class.java -> {
- resId = R.drawable.ic_message_attachment_camera
- }
- VKAudio::class.java -> {
- resId = R.drawable.ic_message_attachment_audio
- }
- VKVideo::class.java -> {
- resId = R.drawable.ic_message_attachment_video
- }
- VKDoc::class.java -> {
- resId = R.drawable.ic_message_attachment_doc
- }
- VKGraffiti::class.java -> {
- resId = R.drawable.ic_message_attachment_graffiti
- }
- VKAudioMessage::class.java -> {
- resId = R.drawable.ic_message_attachment_audio_message
- }
- VKSticker::class.java -> {
- resId = R.drawable.ic_message_attachment_sticker
- }
- VKGift::class.java -> {
- resId = R.drawable.ic_message_attachment_gift
- }
- VKLink::class.java -> {
- resId = R.drawable.ic_message_attachment_link
- }
- VKPoll::class.java -> {
- resId = R.drawable.ic_message_attachment_poll
- }
- VKCall::class.java -> {
- resId = R.drawable.ic_message_attachment_call
- }
- }
-
- if (resId != -1) {
- val drawable = context.drawable(resId)
-
- drawable?.setTint(context.color(R.color.accent))
- return drawable
- }
- return null
- }
-
- fun getFwdText(context: Context, forwardedMessages: List): String {
- return if (forwardedMessages.isNotEmpty()) {
- if (forwardedMessages.size > 1) {
- context.getString(R.string.message_fwd_many, forwardedMessages.size).lowerCase()
- } else {
- context.getString(R.string.message_fwd_one)
- }
- } else ""
- }
-
- @Deprecated("need to rewrite")
- fun getActionText(
- context: Context,
- lastMessage: VKMessage,
- onResponseListener: OnResponseListener
- ) {
- TaskManager.execute {
- lastMessage.action?.let {
- var result = ""
-
- when (it.type) {
- VKMessageAction.ACTION_CHAT_CREATE -> result = context.getString(
- R.string.message_action_created_chat,
- ""
- )
- VKMessageAction.ACTION_INVITE_USER -> result =
- if (lastMessage.fromId == lastMessage.action!!.memberId) {
- context.getString(R.string.message_action_returned_to_chat, "")
- } else {
- val invited = MemoryCache.getUserById(lastMessage.action!!.memberId)
- context.getString(R.string.message_action_invited_user, invited)
- }
- VKMessageAction.ACTION_INVITE_USER_BY_LINK -> result = context.getString(
- R.string.message_action_invited_by_link,
- ""
- )
- VKMessageAction.ACTION_KICK_USER -> result =
- if (lastMessage.fromId == lastMessage.action!!.memberId) {
- context.getString(R.string.message_action_left_from_chat, "")
- } else {
- val kicked = MemoryCache.getUserById(lastMessage.action!!.memberId)
- context.getString(R.string.message_action_kicked_user, kicked)
- }
- VKMessageAction.ACTION_PHOTO_REMOVE -> result = context.getString(
- R.string.message_action_removed_photo,
- ""
- )
- VKMessageAction.ACTION_PHOTO_UPDATE -> result = context.getString(
- R.string.message_action_updated_photo,
- ""
- )
- VKMessageAction.ACTION_PIN_MESSAGE -> result = context.getString(
- R.string.message_action_pinned_message,
- ""
- )
- VKMessageAction.ACTION_UNPIN_MESSAGE -> result = context.getString(
- R.string.message_action_unpinned_message,
- ""
- )
- VKMessageAction.ACTION_TITLE_UPDATE -> result = context.getString(
- R.string.message_action_updated_title,
- ""
- )
- }
-
- AppGlobal.post { onResponseListener.onResponse(result) }
- }
- }
- }
-
- fun getTime(context: Context, lastMessage: VKMessage): String {
- val then = lastMessage.date * 1000L
- val now = System.currentTimeMillis()
-
- val change = abs(now - then)
-
- val seconds = change / 1000
-
- if (seconds == 0L) {
- return context.getString(R.string.time_format_now)
- }
-
- val minutes = seconds / 60
-
- if (minutes == 0L) {
- return context.getString(R.string.time_format_second, seconds)
- }
-
- val hours = minutes / 60
-
- if (hours == 0L) {
- return context.getString(R.string.time_format_minute, minutes)
- }
-
- val days = hours / 24
-
- if (days == 0L) {
- return context.getString(R.string.time_format_hour, hours)
- }
-
- val months = days / 30
-
- if (months == 0L) {
- return context.getString(R.string.time_format_day, days)
- }
-
- val years = months / 12
-
- if (years == 0L) {
- return context.getString(R.string.time_format_month, months)
- } else if (years > 0L) {
- return context.getString(R.string.time_format_year, years)
- }
-
- return SimpleDateFormat("HH:mm", Locale.getDefault()).format(then)
- }
-
- fun parseConversations(array: JSONArray): ArrayList {
- val conversations = arrayListOf()
- for (i in 0 until array.length()) {
- conversations.add(VKConversation(array.optJSONObject(i)))
- }
-
- return conversations
- }
-
- fun parseMessages(array: JSONArray): ArrayList {
- val messages = arrayListOf()
- for (i in 0 until array.length()) {
- messages.add(VKMessage(array.optJSONObject(i)))
- }
-
- return messages
- }
-
- fun isChatId(id: Int) = id > 2_000_000_000
-
- fun isMessageHasFlag(mask: Int, flagName: String): Boolean {
- val o: Any? = VKMessage.flags[flagName]
- return if (o != null) { //has flag
- val flag = o as Int
- flag and mask > 0
- } else false
- }
-
- //TODO: rewrite parsing
- //fromUser and fromGroup are null
- @Deprecated("need to rewrite")
- @WorkerThread
- fun parseLongPollMessage(array: JSONArray): VKMessage {
- val message = VKMessage()
-
- val id = array.optInt(1)
- val flags = array.optInt(2)
- val peerId = array.optInt(3)
- val date = array.optInt(4)
- val text = array.optString(5)
-
- message.messageId = id
- message.peerId = peerId
- message.date = date
- message.text = text
-
- val fromId =
- if (isMessageHasFlag(flags, "outbox")) UserConfig.userId
- else peerId
-
- message.fromId = fromId
-
- array.optJSONObject(6)?.let {
- if (it.has("emoji")) message.hasEmoji = true
-
- if (it.has("from")) {
- message.fromId = it.optInt("from", -1)
- }
-
- if (it.has("source_act")) {
- message.action = VKMessageAction().also { action ->
- action.type = it.optString("source_act")
-
- when (action.type) {
- VKMessageAction.ACTION_CHAT_CREATE -> {
- action.text = it.optString("source_text")
- }
- VKMessageAction.ACTION_TITLE_UPDATE -> {
- action.oldText = it.optString("source_old_text")
- action.text = it.optString("source_text")
- }
- VKMessageAction.ACTION_PIN_MESSAGE -> {
- action.memberId = it.optInt("source_mid")
- action.conversationMessageId = it.optInt("source_chat_local_id")
-
- it.optJSONObject("source_message")?.let { message ->
- action.message = VKMessage(message)
- }
- }
- VKMessageAction.ACTION_UNPIN_MESSAGE -> {
- action.memberId = it.optInt("source_mid")
- action.conversationMessageId = it.optInt("source_chat_local_id")
- }
- VKMessageAction.ACTION_INVITE_USER,
- VKMessageAction.ACTION_KICK_USER,
- VKMessageAction.ACTION_SCREENSHOT,
- VKMessageAction.ACTION_INVITE_USER_BY_CALL -> {
- action.memberId = it.optInt("source_mid")
- }
- }
- }
- }
- }
-
- array.optJSONObject(7)?.let {
- /**
- *
- * fwd? reply? attachments_count? attachments?
- *
- */
- }
-
- val randomId = array.optInt(8)
- message.randomId = randomId
-
- val conversationMessageId = array.optInt(9)
- message.conversationMessageId = conversationMessageId
-
- val editTime = array.optInt(10)
- message.editTime = editTime
-
- val out = fromId == UserConfig.userId
- message.isOut = out
-
- if (message.isFromUser()) {
- message.fromUser = MemoryCache.getUserById(fromId)
- } else {
- message.fromGroup = MemoryCache.getGroupById(abs(fromId))
- }
-
- return message
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/base/BaseActivity.kt b/app/src/main/java/com/meloda/fast/base/BaseActivity.kt
index 201a16b5..4e800f3d 100644
--- a/app/src/main/java/com/meloda/fast/base/BaseActivity.kt
+++ b/app/src/main/java/com/meloda/fast/base/BaseActivity.kt
@@ -4,8 +4,8 @@ import android.os.Build
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
+import com.meloda.extensions.ContextExtensions.color
import com.meloda.fast.R
-import com.meloda.fast.extensions.ContextExtensions.color
import com.meloda.fast.util.AndroidUtils
import com.meloda.fast.util.ColorUtils
diff --git a/app/src/main/java/com/meloda/fast/base/BaseAdapter.kt b/app/src/main/java/com/meloda/fast/base/BaseAdapter.kt
index 5aca83aa..e5982b94 100644
--- a/app/src/main/java/com/meloda/fast/base/BaseAdapter.kt
+++ b/app/src/main/java/com/meloda/fast/base/BaseAdapter.kt
@@ -8,8 +8,8 @@ import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
import androidx.recyclerview.widget.RecyclerView
+import com.meloda.arrayutils.ArrayUtils.asArrayList
import com.meloda.fast.common.AppGlobal
-import com.meloda.fast.extensions.ArrayExtensions.asArrayList
import com.meloda.fast.listener.ItemClickListener
import com.meloda.fast.listener.ItemLongClickListener
import java.io.Serializable
@@ -17,16 +17,16 @@ import java.util.*
@Suppress("UNCHECKED_CAST")
-abstract class BaseAdapter(
+abstract class BaseAdapter- (
var context: Context,
- var values: ArrayList = arrayListOf()
+ var values: ArrayList
- = arrayListOf()
) : RecyclerView.Adapter() {
companion object {
private const val P_ITEMS = "BaseAdapter.values"
}
- private var cleanValues: ArrayList? = null
+ private var cleanValues: ArrayList
- ? = null
private var inflater: LayoutInflater = LayoutInflater.from(context)
@@ -35,36 +35,36 @@ abstract class BaseAdapter(
open fun destroy() {}
- open fun getItem(position: Int): T {
+ open fun getItem(position: Int): Item {
return values[position]
}
- fun add(position: Int, item: T) {
+ fun add(position: Int, item: Item) {
values.add(position, item)
cleanValues?.add(position, item)
}
- fun add(item: T) {
+ fun add(item: Item) {
values.add(item)
cleanValues?.add(item)
}
- fun addAll(items: List) {
+ fun addAll(items: List
- ) {
values.addAll(items)
cleanValues?.addAll(items)
}
- fun addAll(position: Int, items: List) {
+ fun addAll(position: Int, items: List
- ) {
values.addAll(position, items)
cleanValues?.addAll(position, items)
}
- operator fun set(position: Int, item: T) {
+ operator fun set(position: Int, item: Item) {
values[position] = item
cleanValues?.set(position, item)
}
- fun indexOf(item: T): Int {
+ fun indexOf(item: Item): Int {
return values.indexOf(item)
}
@@ -73,11 +73,13 @@ abstract class BaseAdapter(
cleanValues?.removeAt(index)
}
- fun remove(item: T) {
+ fun remove(item: Item) {
values.remove(item)
cleanValues?.remove(item)
}
+ open fun notifyChanges(oldList: List
- , newList: List
- = values) {}
+
fun isEmpty() = values.isNullOrEmpty()
fun isNotEmpty() = !isEmpty()
@@ -86,12 +88,12 @@ abstract class BaseAdapter(
return inflater.inflate(resId, viewGroup, false)
}
- fun updateValues(arrayList: ArrayList) {
+ fun updateValues(arrayList: ArrayList
- ) {
values.clear()
values.addAll(arrayList)
}
- fun updateValues(list: List) = updateValues(list.asArrayList())
+ fun updateValues(list: List
- ) = updateValues(list.asArrayList())
override fun onBindViewHolder(holder: VH, position: Int) {
onBindItemViewHolder(holder, position)
@@ -135,7 +137,7 @@ abstract class BaseAdapter(
fun onRestoreInstanceState(state: Parcelable?) {
if (state is Bundle) {
if (state.containsKey(P_ITEMS)) {
- values = state.getSerializable(P_ITEMS) as ArrayList
+ values = state.getSerializable(P_ITEMS) as ArrayList
-
}
}
}
@@ -164,11 +166,11 @@ abstract class BaseAdapter(
notifyDataSetChanged()
}
- open fun onQueryItem(item: T, query: String): Boolean {
+ open fun onQueryItem(item: Item, query: String): Boolean {
return false
}
- operator fun get(index: Int): T {
+ operator fun get(index: Int): Item {
return values[index]
}
diff --git a/app/src/main/java/com/meloda/fast/base/BaseFragment.kt b/app/src/main/java/com/meloda/fast/base/BaseFragment.kt
index b13a1e51..dc5159b2 100644
--- a/app/src/main/java/com/meloda/fast/base/BaseFragment.kt
+++ b/app/src/main/java/com/meloda/fast/base/BaseFragment.kt
@@ -3,7 +3,7 @@ package com.meloda.fast.base
import androidx.annotation.IdRes
import androidx.appcompat.widget.Toolbar
import androidx.fragment.app.Fragment
-import com.meloda.fast.activity.MainActivityDeprecated
+import com.meloda.fast.activity.MainActivity
abstract class BaseFragment : Fragment() {
@@ -11,13 +11,13 @@ abstract class BaseFragment : Fragment() {
val toolbar: Toolbar = requireView().findViewById(resId)
activity?.let {
- if (it is MainActivityDeprecated && toolbar is com.meloda.fast.widget.Toolbar) it.initToolbar(
+ if (it is MainActivity && toolbar is com.meloda.fast.widget.Toolbar) it.initToolbar(
toolbar
)
}
}
- protected fun runOnUi(runnable: Runnable) {
+ fun runOnUiThread(runnable: Runnable) {
activity?.runOnUiThread(runnable)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/base/BaseHolder.kt b/app/src/main/java/com/meloda/fast/base/BaseHolder.kt
index c7fccaf7..563da0a7 100644
--- a/app/src/main/java/com/meloda/fast/base/BaseHolder.kt
+++ b/app/src/main/java/com/meloda/fast/base/BaseHolder.kt
@@ -4,5 +4,11 @@ import android.view.View
import androidx.recyclerview.widget.RecyclerView
abstract class BaseHolder(v: View) : RecyclerView.ViewHolder(v) {
- abstract fun bind(position: Int)
+
+ open fun bind(position: Int) {
+ bind(position, mutableListOf())
+ }
+
+ open fun bind(position: Int, payloads: MutableList?) {}
+
}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/base/FragmentStackActivity.kt b/app/src/main/java/com/meloda/fast/base/FragmentStackActivity.kt
deleted file mode 100644
index 1b3b2e8a..00000000
--- a/app/src/main/java/com/meloda/fast/base/FragmentStackActivity.kt
+++ /dev/null
@@ -1,6 +0,0 @@
-package com.meloda.fast.base
-
-abstract class FragmentStackActivity : BaseActivity() {
-
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/common/AppGlobal.kt b/app/src/main/java/com/meloda/fast/common/AppGlobal.kt
index 429bc344..69af67ef 100644
--- a/app/src/main/java/com/meloda/fast/common/AppGlobal.kt
+++ b/app/src/main/java/com/meloda/fast/common/AppGlobal.kt
@@ -8,6 +8,7 @@ import android.content.Context
import android.content.SharedPreferences
import android.content.pm.PackageManager
import android.content.res.Resources
+import android.database.sqlite.SQLiteDatabase
import android.net.ConnectivityManager
import android.os.Handler
import android.view.WindowManager
@@ -15,13 +16,12 @@ import android.view.inputmethod.InputMethodManager
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.content.pm.PackageInfoCompat
import androidx.preference.PreferenceManager
-import androidx.room.Room
import com.facebook.drawee.backends.pipeline.Fresco
import com.meloda.fast.BuildConfig
import com.meloda.fast.R
-import com.meloda.fast.api.UserConfig
-import com.meloda.fast.database.AppDatabase
-import com.meloda.fast.database.MemoryCache
+import com.meloda.fast.UserConfig
+import com.meloda.fast.database.CacheStorage
+import com.meloda.fast.database.DatabaseHelper
import com.meloda.fast.fragment.SettingsFragment
import com.meloda.fast.util.AndroidUtils
import com.meloda.mvp.MvpBase
@@ -59,9 +59,11 @@ class AppGlobal : Application() {
lateinit var handler: Handler
lateinit var resources: Resources
lateinit var packageName: String
- lateinit var database: AppDatabase
lateinit var instance: AppGlobal
+ lateinit var dbHelper: DatabaseHelper
+ lateinit var database: SQLiteDatabase
+
lateinit var packageManager: PackageManager
var versionName = ""
@@ -89,14 +91,13 @@ class AppGlobal : Application() {
Fresco.initialize(this)
- database = Room.databaseBuilder(this, AppDatabase::class.java, "cache")
- .fallbackToDestructiveMigration()
- .build()
-
preferences = PreferenceManager.getDefaultSharedPreferences(this)
handler = Handler(mainLooper)
locale = Locale.getDefault()
+ dbHelper = DatabaseHelper(this)
+ database = dbHelper.writableDatabase
+
val info = packageManager.getPackageInfo(this.packageName, PackageManager.GET_ACTIVITIES)
versionName = info.versionName
versionCode = PackageInfoCompat.getLongVersionCode(info)
@@ -118,19 +119,23 @@ class AppGlobal : Application() {
MvpBase.init(handler)
+ logDatabase()
fillMemoryCache()
applyNightMode()
}
- private fun fillMemoryCache() {
- TaskManager.execute {
- val users = database.users.getAll()
- val groups = database.groups.getAll()
+ private fun logDatabase() {
+ val users = CacheStorage.usersStorage.getAllValues()
+ val groups = CacheStorage.groupsStorage.getAllValues()
+ val chats = CacheStorage.chatsStorage.getAllValues()
+ val messages = CacheStorage.messagesStorage.getAllValues()
+
+ return
+ }
+
+ private fun fillMemoryCache() {
- MemoryCache.appendUsers(users)
- MemoryCache.appendGroups(groups)
- }
}
fun applyNightMode(value: String? = null): Int {
diff --git a/app/src/main/java/com/meloda/fast/common/TaskManager.kt b/app/src/main/java/com/meloda/fast/common/TaskManager.kt
deleted file mode 100644
index 5ea9dcbd..00000000
--- a/app/src/main/java/com/meloda/fast/common/TaskManager.kt
+++ /dev/null
@@ -1,363 +0,0 @@
-package com.meloda.fast.common
-
-import android.util.Log
-import com.meloda.fast.BuildConfig
-import com.meloda.fast.api.VKApi
-import com.meloda.fast.api.VKApiKeys
-import com.meloda.fast.api.method.MethodSetter
-import com.meloda.fast.api.model.VKConversation
-import com.meloda.fast.api.model.VKGroup
-import com.meloda.fast.api.model.VKMessage
-import com.meloda.fast.api.model.VKUser
-import com.meloda.fast.concurrent.LowThread
-import com.meloda.fast.database.MemoryCache
-import com.meloda.fast.event.EventInfo
-import com.meloda.fast.listener.OnResponseListener
-import java.util.*
-import java.util.stream.Collectors
-
-object TaskManager {
-
- private const val TAG = "TaskManager"
-
- private val groupsTasksIds = arrayListOf()
-
- private var groupsTimer: Timer? = null
-
- private val usersTasksIds = arrayListOf()
-
- private var usersTimer: Timer? = null
-
- private val messagesTasksIds = arrayListOf()
-
- private val messagesReadIds = arrayListOf()
-
- private var messagesReadTimer: Timer? = null
-
- private val conversationsTasksIds = arrayListOf()
-
- private val listeners = arrayListOf()
-
- fun addOnEventListener(listener: OnEventListener?) {
- listeners.add(listener)
- }
-
- fun removeOnEventListener(listener: OnEventListener?) {
- listeners.remove(listener)
- }
-
- fun execute(runnable: Runnable?) {
- LowThread(runnable).start()
- }
-
- private fun addProcedure(
- methodSetter: MethodSetter,
- className: Class,
- pushInfo: EventInfo<*>?,
- responseListener: OnResponseListener?
- ) {
- execute {
- methodSetter.executeArray(className, object : OnResponseListener> {
- override fun onResponse(response: ArrayList) {
- if (response.isEmpty()) return
-
- responseListener?.onResponse(response[0])
-
- pushInfo?.let { sendEvent(it) }
- }
-
- override fun onError(t: Throwable) {
- responseListener?.onError(t)
- }
-
- })
- }
- }
-
- fun sendEvent(eventInfo: EventInfo<*>) {
- AppGlobal.handler.post {
- for (listener in listeners) {
- listener?.onNewEvent(eventInfo)
- }
- }
- }
-
- fun loadUser(
- eventKey: VKApiKeys,
- userId: Int,
- responseListener: OnResponseListener? = null
- ) {
- if (usersTasksIds.contains(userId)) return
- usersTasksIds.add(userId)
-
- if (BuildConfig.DEBUG) {
- Log.i(TAG, "Load user: $userId")
- }
-
- if (usersTimer != null) {
- usersTimer?.cancel()
- }
-
- usersTimer = Timer()
- usersTimer?.schedule(object : TimerTask() {
- override fun run() {
- val setter = VKApi.users()
- .get()
- .userIds(usersTasksIds)
- .fields(VKUser.DEFAULT_FIELDS)
-
- val usersIds = arrayListOf()
- usersTasksIds.forEach { usersIds.add(it.toString()) }
-
- addProcedure(
- setter,
- VKUser::class.java,
- EventInfo(eventKey, usersTasksIds),
- object : OnResponseListener {
- override fun onResponse(response: VKUser) {
- Log.d(
- TAG,
- "Loaded users: ${
- usersIds.stream().collect(Collectors.joining(", "))
- }"
- )
-
- usersTasksIds.remove(userId)
- responseListener?.onResponse(response)
-
- execute { MemoryCache.put(response) }
- }
-
- override fun onError(t: Throwable) {
- Log.w(
- TAG,
- "Loaded users: ${
- usersIds.stream().collect(Collectors.joining(", "))
- }\nStack:${Log.getStackTraceString(t)}"
- )
- responseListener?.onError(t)
- }
-
- })
-
- usersTimer = null
- }
- }, 500)
- }
-
- fun loadGroup(
- eventKey: VKApiKeys,
- groupId: Int,
- responseListener: OnResponseListener? = null
- ) {
- if (groupsTasksIds.contains(groupId)) return
- groupsTasksIds.add(groupId)
-
- if (BuildConfig.DEBUG) {
- Log.i(TAG, "Load group: $groupId")
- }
-
- val setter = VKApi.groups().getById()
- .groupIds(groupsTasksIds)
- .fields(VKGroup.DEFAULT_FIELDS)
-
- if (groupsTimer != null) {
- groupsTimer?.cancel()
- }
-
- groupsTimer = Timer()
- groupsTimer?.schedule(object : TimerTask() {
- override fun run() {
- val groupsIds = arrayListOf()
- groupsTasksIds.forEach { groupsIds.add(it.toString()) }
-
- addProcedure(
- setter,
- VKGroup::class.java,
- EventInfo(eventKey, groupsTasksIds),
- object : OnResponseListener {
- override fun onResponse(response: VKGroup) {
- Log.d(
- TAG,
- "Loaded groups: ${
- groupsIds.stream().collect(Collectors.joining(", "))
- }"
- )
-
- groupsTasksIds.remove(groupId)
- responseListener?.onResponse(response)
-
- execute { MemoryCache.put(response) }
- }
-
- override fun onError(t: Throwable) {
- Log.w(
- TAG,
- "Not loaded Group: ${
- groupsIds.stream().collect(Collectors.joining(", "))
- }\nStack: " + Log.getStackTraceString(
- t
- )
- )
- responseListener?.onError(t)
- }
- })
- }
- }, 500)
-
- }
-
- fun loadMessage(
- eventKey: VKApiKeys,
- messageId: Int,
- responseListener: OnResponseListener? = null
- ) {
- if (BuildConfig.DEBUG) {
- Log.i(TAG, "Load message: $messageId")
- }
- if (messagesTasksIds.contains(messageId)) return
- messagesTasksIds.add(messageId)
-
- val setter = VKApi.messages().getById()
- .messageIds(messageId)
- .extended(true)
- .filter(VKUser.DEFAULT_FIELDS + "," + VKGroup.DEFAULT_FIELDS)
-
- addProcedure(
- setter,
- VKMessage::class.java,
- EventInfo(eventKey, messageId),
- object : OnResponseListener {
- override fun onResponse(response: VKMessage) {
- Log.d(TAG, "Loaded message: $messageId")
-
- messagesTasksIds.remove(messageId)
- responseListener?.onResponse(response)
-
- execute { MemoryCache.put(response) }
- }
-
- override fun onError(t: Throwable) {
- Log.w(
- TAG,
- "Not loaded message: $messageId. Stack: " + Log.getStackTraceString(t)
- )
- responseListener?.onError(t)
- }
- })
- }
-
- fun readMessage(
- eventKey: VKApiKeys,
- peerId: Int,
- messageId: Int,
- responseListener: OnResponseListener? = null
- ) {
- if (messagesReadIds.contains(messageId)) return
- messagesReadIds.add(messageId)
-
- if (BuildConfig.DEBUG) {
- Log.i(TAG, "Read message: $messageId")
- }
-
- if (messagesReadTimer != null) {
- messagesReadTimer?.cancel()
- }
-
- messagesReadTimer = Timer()
- messagesReadTimer?.schedule(object : TimerTask() {
- override fun run() {
- val messagesIds = arrayListOf()
- messagesReadIds.forEach { messagesIds.add(it.toString()) }
-
- val setter = VKApi.messages().markAsRead()
-// .startMessageId(messageId)
- .markConversationAsRead(true)
- .peerId(peerId)
-
- addProcedure(
- setter,
- Int::class.java,
- EventInfo(eventKey, arrayOf(peerId, messageId)),
- object : OnResponseListener {
- override fun onResponse(response: Int) {
- Log.d(
- TAG,
- "Readed messages: ${
- messagesIds.stream().collect(Collectors.joining(", "))
- }"
- )
-
- messagesReadIds.remove(messageId)
- responseListener?.onResponse(response)
-
- //TODO: update readed messages in cache
-// execute { MemoryCache.put(response) }
- }
-
- override fun onError(t: Throwable) {
- Log.w(
- TAG,
- "Not readed messages: ${
- messagesIds.stream().collect(Collectors.joining(", "))
- }\nStack: " + Log.getStackTraceString(
- t
- )
- )
- responseListener?.onError(t)
- }
- }
- )
- }
-
- }, 500)
- }
-
- fun loadConversation(
- eventKey: VKApiKeys,
- conversationId: Int,
- responseListener: OnResponseListener? = null
- ) {
- if (BuildConfig.DEBUG) {
- Log.i(TAG, "Load conversation: $conversationId")
- }
- if (conversationsTasksIds.contains(conversationId)) return
- conversationsTasksIds.add(conversationId)
-
- val setter = VKApi.messages()
- .getConversationsById()
- .peerIds(conversationId)
- .extended(true)
- .fields(VKUser.DEFAULT_FIELDS + "," + VKGroup.DEFAULT_FIELDS)
-
- addProcedure(
- setter,
- VKConversation::class.java,
- EventInfo(eventKey, conversationId),
- object : OnResponseListener {
- override fun onResponse(response: VKConversation) {
- Log.d(TAG, "Loaded conversation: $conversationId")
-
- conversationsTasksIds.remove(conversationId)
- responseListener?.onResponse(response)
-
- execute { MemoryCache.put(response) }
- }
-
- override fun onError(t: Throwable) {
- Log.w(
- TAG,
- "Not loaded conversation: $conversationId. Stack: " + Log.getStackTraceString(
- t
- )
- )
- responseListener?.onError(t)
- }
-
- })
- }
-
- interface OnEventListener {
- fun onNewEvent(info: EventInfo<*>)
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/common/UpdateManager.kt b/app/src/main/java/com/meloda/fast/common/UpdateManager.kt
index 25af52f3..1d7669bf 100644
--- a/app/src/main/java/com/meloda/fast/common/UpdateManager.kt
+++ b/app/src/main/java/com/meloda/fast/common/UpdateManager.kt
@@ -2,9 +2,10 @@ package com.meloda.fast.common
import android.util.Log
import androidx.collection.arrayMapOf
+import com.meloda.concurrent.TaskManager
import com.meloda.fast.BuildConfig
import com.meloda.fast.model.NewUpdateInfo
-import com.meloda.fast.net.HttpRequest
+import com.meloda.netservices.HttpRequest
import org.json.JSONArray
import org.json.JSONObject
diff --git a/app/src/main/java/com/meloda/fast/database/AppDatabase.kt b/app/src/main/java/com/meloda/fast/database/AppDatabase.kt
deleted file mode 100644
index 53cefe2c..00000000
--- a/app/src/main/java/com/meloda/fast/database/AppDatabase.kt
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.meloda.fast.database
-
-import androidx.room.Database
-import androidx.room.RoomDatabase
-import com.meloda.fast.api.model.*
-import com.meloda.fast.database.dao.*
-
-@Database(
- entities = [VKConversation::class, VKMessage::class, VKUser::class, VKGroup::class, VKFriend::class],
- version = 1,
- exportSchema = false
-)
-
-abstract class AppDatabase : RoomDatabase() {
- abstract val conversations: ConversationsDao
- abstract val messages: MessagesDao
- abstract val users: UsersDao
- abstract val groups: GroupsDao
- abstract val friends: FriendsDao
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/database/CacheStorage.kt b/app/src/main/java/com/meloda/fast/database/CacheStorage.kt
new file mode 100644
index 00000000..2b1d9afe
--- /dev/null
+++ b/app/src/main/java/com/meloda/fast/database/CacheStorage.kt
@@ -0,0 +1,115 @@
+package com.meloda.fast.database
+
+import android.content.ContentValues
+import android.database.Cursor
+import android.os.Bundle
+import com.meloda.fast.common.AppGlobal.Companion.database
+import com.meloda.fast.database.DatabaseUtils.TABLE_CHATS
+import com.meloda.fast.database.DatabaseUtils.TABLE_FRIENDS
+import com.meloda.fast.database.DatabaseUtils.TABLE_MESSAGES
+import com.meloda.fast.database.DatabaseUtils.TABLE_USERS
+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.vksdk.model.VKConversation
+import com.meloda.vksdk.model.VKMessage
+import com.meloda.vksdk.model.VKUser
+import java.util.*
+
+object CacheStorage {
+
+ val usersStorage = UsersStorage()
+ val messagesStorage = MessagesStorage()
+ val chatsStorage = ChatsStorage()
+ val groupsStorage = GroupsStorage()
+
+ fun selectCursor(tableName: String): Cursor {
+ return QueryBuilder.query()
+ .select("*").from(tableName)
+ .asCursor(database)
+ }
+
+ fun selectCursor(tableName: String, where: String): Cursor {
+ return QueryBuilder.query()
+ .select("*").from(tableName)
+ .where(where)
+ .asCursor(database)
+ }
+
+ fun selectCursor(tableName: String, columnName: String, value: Any): Cursor {
+ return QueryBuilder.query()
+ .select("*").from(tableName)
+ .where("$columnName=$value")
+ .asCursor(database)
+ }
+
+ fun selectCursor(tableName: String, columnName: String, ids: IntArray): Cursor {
+ val where = StringBuilder(5 * ids.size)
+
+ where.append("$columnName=${ids[0]}")
+
+ for (i in 1 until ids.size) {
+ where.append(" OR ")
+ where.append("$columnName=${ids[i]}")
+ }
+
+ return selectCursor(tableName, where.toString())
+ }
+
+ fun getInt(cursor: Cursor, columnName: String) =
+ cursor.getInt(cursor.getColumnIndexOrThrow(columnName))
+
+ fun getString(cursor: Cursor, columnName: String) =
+ cursor.getString(cursor.getColumnIndexOrThrow(columnName))
+
+ fun getBlob(cursor: Cursor, columnName: String) =
+ cursor.getBlob(cursor.getColumnIndexOrThrow(columnName))
+
+ fun insert(tableName: String, values: ArrayList) {
+ database.beginTransaction()
+
+ val contentValues = ContentValues()
+
+ for (value in values) {
+ when (tableName) {
+ TABLE_USERS -> {
+ usersStorage.cacheValue(contentValues, value as VKUser)
+ break
+ }
+ TABLE_FRIENDS -> {
+ usersStorage.cacheValue(
+ contentValues,
+ value as VKUser,
+ Bundle().apply { putBoolean("toFriends", true) })
+ break
+ }
+ TABLE_MESSAGES -> {
+ messagesStorage.cacheValue(contentValues, value as VKMessage)
+ break
+ }
+ TABLE_CHATS -> {
+ chatsStorage.cacheValue(contentValues, value as VKConversation)
+ break
+ }
+ }
+
+ database.insert(tableName, null, contentValues)
+ contentValues.clear()
+ }
+
+ database.setTransactionSuccessful()
+ database.endTransaction()
+ }
+
+ fun delete(tableName: String, whereClause: String, vararg whereArgs: String) {
+ database.delete(tableName, whereClause, whereArgs)
+ }
+
+ fun delete(tableName: String) {
+ database.delete(tableName, null, null)
+ }
+
+
+}
+
diff --git a/app/src/main/java/com/meloda/fast/database/DatabaseHelper.kt b/app/src/main/java/com/meloda/fast/database/DatabaseHelper.kt
new file mode 100644
index 00000000..39385c3c
--- /dev/null
+++ b/app/src/main/java/com/meloda/fast/database/DatabaseHelper.kt
@@ -0,0 +1,29 @@
+package com.meloda.fast.database
+
+import android.content.Context
+import android.database.sqlite.SQLiteDatabase
+import android.database.sqlite.SQLiteOpenHelper
+
+class DatabaseHelper constructor(context: Context) : SQLiteOpenHelper(
+ context,
+ DB_NAME,
+ null,
+ DB_VERSION
+) {
+ companion object {
+ private const val DB_NAME = "cache.db"
+ private const val DB_VERSION = 1
+ }
+
+ override fun onCreate(db: SQLiteDatabase) {
+ db.execSQL(DatabaseUtils.createUsersTable())
+ db.execSQL(DatabaseUtils.createGroupsTable())
+ db.execSQL(DatabaseUtils.createFriendsTable())
+ db.execSQL(DatabaseUtils.createMessagesTable())
+ db.execSQL(DatabaseUtils.createChatsTable())
+ }
+
+ override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/database/DatabaseKeys.kt b/app/src/main/java/com/meloda/fast/database/DatabaseKeys.kt
new file mode 100644
index 00000000..b9c446c0
--- /dev/null
+++ b/app/src/main/java/com/meloda/fast/database/DatabaseKeys.kt
@@ -0,0 +1,95 @@
+package com.meloda.fast.database
+
+object DatabaseKeys {
+
+ const val ID = "_id"
+
+ const val SORT_ID = "_sort_id"
+
+ const val USER_ID = "_user_id"
+
+ const val FIRST_NAME = "_first_name"
+
+ const val LAST_NAME = "_last_name"
+
+ const val DEACTIVATED = "_deactivated"
+
+ const val GENDER = "_gender"
+
+ const val SCREEN_NAME = "_screen_name"
+
+ const val PHOTOS = "_photos"
+
+ const val IS_ONLINE = "_is_online"
+
+ const val IS_ONLINE_MOBILE = "_is_online_mobile"
+
+ const val STATUS = "_status"
+
+ const val LAST_SEEN = "_last_seen"
+
+ const val MESSAGE_ID = "_message_id"
+
+ const val DATE = "_date"
+
+ const val PEER_ID = "_peer_id"
+
+ const val FROM_ID = "_from_id"
+
+ const val EDIT_TIME = "_edit_time"
+
+ const val IS_OUT = "_is_out"
+
+ const val TEXT = "_text"
+
+ const val RANDOM_ID = "_random_id"
+
+ const val CONVERSATION_MESSAGE_ID = "_conversation_message_id"
+
+ const val ATTACHMENTS = "_attachments"
+
+ const val FWD_MESSAGES = "_fwd_messages"
+
+ const val REPLY_MESSAGE_ID = "_reply_message_id"
+
+ const val ACTION = "_action"
+
+ const val IS_ALLOWED = "_is_allowed"
+
+ const val NOT_ALLOWED_REASON = "_not_allowed_reason"
+
+ const val IN_READ_MESSAGE_ID = "_in_read_message_id"
+
+ const val OUT_READ_MESSAGE_ID = "_out_read_message_id"
+
+ const val LAST_MESSAGE_ID = "_last_message_id"
+
+ const val UNREAD_COUNT = "_unread_count"
+
+ const val CONVERSATION_ID = "_conversation_id"
+
+ const val TYPE = "_type"
+
+ const val LOCAL_ID = "_local_id"
+
+ const val IS_NOTIFICATIONS_DISABLED = "_is_notifications_disabled"
+
+ const val MEMBERS_COUNT = "_members_count"
+
+ const val TITLE = "_title"
+
+ const val PINNED_MESSAGE_ID = "_pinned_message_id"
+
+ const val CHAT_STATE = "_chat_state"
+
+ const val IS_GROUP_CHANNEL = "_is_group_channel"
+
+ const val FRIEND_ID = "_friend_id"
+
+ const val GROUP_ID = "_group_id"
+
+ const val NAME = "_name"
+
+ const val IS_CLOSED = "_is_closed"
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/database/DatabaseUtils.kt b/app/src/main/java/com/meloda/fast/database/DatabaseUtils.kt
new file mode 100644
index 00000000..10f8eb19
--- /dev/null
+++ b/app/src/main/java/com/meloda/fast/database/DatabaseUtils.kt
@@ -0,0 +1,153 @@
+package com.meloda.fast.database
+
+import com.meloda.fast.database.DatabaseKeys.ACTION
+import com.meloda.fast.database.DatabaseKeys.ATTACHMENTS
+import com.meloda.fast.database.DatabaseKeys.CHAT_STATE
+import com.meloda.fast.database.DatabaseKeys.CONVERSATION_ID
+import com.meloda.fast.database.DatabaseKeys.CONVERSATION_MESSAGE_ID
+import com.meloda.fast.database.DatabaseKeys.DATE
+import com.meloda.fast.database.DatabaseKeys.DEACTIVATED
+import com.meloda.fast.database.DatabaseKeys.EDIT_TIME
+import com.meloda.fast.database.DatabaseKeys.FIRST_NAME
+import com.meloda.fast.database.DatabaseKeys.FRIEND_ID
+import com.meloda.fast.database.DatabaseKeys.FROM_ID
+import com.meloda.fast.database.DatabaseKeys.FWD_MESSAGES
+import com.meloda.fast.database.DatabaseKeys.GENDER
+import com.meloda.fast.database.DatabaseKeys.GROUP_ID
+import com.meloda.fast.database.DatabaseKeys.IN_READ_MESSAGE_ID
+import com.meloda.fast.database.DatabaseKeys.IS_ALLOWED
+import com.meloda.fast.database.DatabaseKeys.IS_CLOSED
+import com.meloda.fast.database.DatabaseKeys.IS_GROUP_CHANNEL
+import com.meloda.fast.database.DatabaseKeys.IS_NOTIFICATIONS_DISABLED
+import com.meloda.fast.database.DatabaseKeys.IS_ONLINE
+import com.meloda.fast.database.DatabaseKeys.IS_ONLINE_MOBILE
+import com.meloda.fast.database.DatabaseKeys.IS_OUT
+import com.meloda.fast.database.DatabaseKeys.LAST_MESSAGE_ID
+import com.meloda.fast.database.DatabaseKeys.LAST_NAME
+import com.meloda.fast.database.DatabaseKeys.LAST_SEEN
+import com.meloda.fast.database.DatabaseKeys.LOCAL_ID
+import com.meloda.fast.database.DatabaseKeys.MEMBERS_COUNT
+import com.meloda.fast.database.DatabaseKeys.MESSAGE_ID
+import com.meloda.fast.database.DatabaseKeys.NAME
+import com.meloda.fast.database.DatabaseKeys.NOT_ALLOWED_REASON
+import com.meloda.fast.database.DatabaseKeys.OUT_READ_MESSAGE_ID
+import com.meloda.fast.database.DatabaseKeys.PEER_ID
+import com.meloda.fast.database.DatabaseKeys.PHOTOS
+import com.meloda.fast.database.DatabaseKeys.PINNED_MESSAGE_ID
+import com.meloda.fast.database.DatabaseKeys.RANDOM_ID
+import com.meloda.fast.database.DatabaseKeys.REPLY_MESSAGE_ID
+import com.meloda.fast.database.DatabaseKeys.SCREEN_NAME
+import com.meloda.fast.database.DatabaseKeys.SORT_ID
+import com.meloda.fast.database.DatabaseKeys.STATUS
+import com.meloda.fast.database.DatabaseKeys.TEXT
+import com.meloda.fast.database.DatabaseKeys.TITLE
+import com.meloda.fast.database.DatabaseKeys.TYPE
+import com.meloda.fast.database.DatabaseKeys.UNREAD_COUNT
+import com.meloda.fast.database.DatabaseKeys.USER_ID
+
+object DatabaseUtils {
+
+ const val TABLE_USERS = "users"
+ const val TABLE_MESSAGES = "messages"
+ const val TABLE_CHATS = "chats"
+ const val TABLE_FRIENDS = "friends"
+ const val TABLE_GROUPS = "groups"
+
+ private val usersTableMap = HashMap().apply {
+ this[USER_ID] = "integer primary key on conflict replace"
+ this[FIRST_NAME] = "varchar(255)"
+ this[LAST_NAME] = "varchar(255)"
+ this[DEACTIVATED] = "varchar(255)"
+ this[GENDER] = "integer default 0"
+ this[SCREEN_NAME] = "varchar(255)"
+ this[PHOTOS] = "text"
+ this[IS_ONLINE] = "integer default 0"
+ this[IS_ONLINE_MOBILE] = "integer default 0"
+ this[STATUS] = "varchar(255)"
+ this[LAST_SEEN] = "integer"
+ }
+
+ private val groupsTableMap = HashMap().apply {
+ this[GROUP_ID] = "integer primary key on conflict replace"
+ this[NAME] = "varchar(255)"
+ this[SCREEN_NAME] = "varchar(255)"
+ this[IS_CLOSED] = "integer default 0"
+ this[DEACTIVATED] = "varchar(255)"
+ this[TYPE] = "varchar(255)"
+ this[PHOTOS] = "text"
+ }
+
+ private val messagesTableMap = HashMap().apply {
+ this[MESSAGE_ID] = "integer primary key on conflict replace"
+ this[DATE] = "integer"
+ this[PEER_ID] = "integer"
+ this[FROM_ID] = "integer"
+ this[EDIT_TIME] = "integer"
+ this[IS_OUT] = "integer default 0"
+ this[TEXT] = "text"
+ this[RANDOM_ID] = "integer"
+ this[CONVERSATION_MESSAGE_ID] = "integer"
+ this[ATTACHMENTS] = "blob"
+ this[REPLY_MESSAGE_ID] = "integer"
+ this[ACTION] = "blob"
+
+ //2,3,4,5 - message_ids
+ this[FWD_MESSAGES] = "text"
+ }
+
+ private val chatsTableMap = HashMap().apply {
+ this[CONVERSATION_ID] = "integer primary key on conflict replace"
+ this[IS_ALLOWED] = "integer default 1"
+ this[NOT_ALLOWED_REASON] = "integer"
+ this[IN_READ_MESSAGE_ID] = "integer"
+ this[OUT_READ_MESSAGE_ID] = "integer"
+ this[LAST_MESSAGE_ID] = "integer"
+ this[UNREAD_COUNT] = "integer"
+ this[LOCAL_ID] = "integer"
+ this[IS_NOTIFICATIONS_DISABLED] = "integer default 0"
+ this[MEMBERS_COUNT] = "integer"
+ this[TITLE] = "varchar(255)"
+ this[IS_GROUP_CHANNEL] = "integer default 0"
+ this[TYPE] = "integer"
+ this[CHAT_STATE] = "integer"
+ this[PHOTOS] = "text"
+
+ this[PINNED_MESSAGE_ID] = "integer"
+ }
+
+ private val friendsTableMap = HashMap().apply {
+ this[FRIEND_ID] = "integer primary key on conflict replace"
+ this[SORT_ID] = "integer"
+
+ //id which user friend
+ this[USER_ID] = "integer"
+ }
+
+ fun createUsersTable() = createTableQuery(TABLE_USERS, usersTableMap)
+ fun createGroupsTable() = createTableQuery(TABLE_GROUPS, groupsTableMap)
+ fun createMessagesTable() = createTableQuery(TABLE_MESSAGES, messagesTableMap)
+ fun createChatsTable() = createTableQuery(TABLE_CHATS, chatsTableMap)
+ fun createFriendsTable() = createTableQuery(TABLE_FRIENDS, friendsTableMap)
+
+ private fun createTableQuery(tableName: String, tableData: HashMap): String {
+ val builder = StringBuilder("create table $tableName (")
+
+ val entry: Map.Entry = tableData.entries.first()
+ builder.append(entry.key)
+ builder.append(" ")
+ builder.append(entry.value)
+
+ tableData.forEach {
+ if (it == entry) return@forEach
+ builder.append(", ")
+ builder.append(it.key)
+ builder.append(" ")
+ builder.append(it.value)
+ }
+
+ builder.append(");")
+
+ return builder.toString();
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/database/MemoryCache.kt b/app/src/main/java/com/meloda/fast/database/MemoryCache.kt
deleted file mode 100644
index c6854729..00000000
--- a/app/src/main/java/com/meloda/fast/database/MemoryCache.kt
+++ /dev/null
@@ -1,176 +0,0 @@
-package com.meloda.fast.database
-
-import android.util.SparseArray
-import androidx.annotation.WorkerThread
-import com.meloda.fast.api.model.*
-import com.meloda.fast.common.AppGlobal
-
-object MemoryCache {
-
- private val users = SparseArray()
- private val groups = SparseArray()
-
- @WorkerThread
- fun getUserById(id: Int): VKUser? {
- var user = users[id]
- if (user == null) {
- user = AppGlobal.database.users.getById(id)
-
- user?.let { append(it) }
- }
- return user
- }
-
- @WorkerThread
- fun getGroupById(positiveId: Int): VKGroup? {
- var group = groups[positiveId]
- if (group == null) {
- group = AppGlobal.database.groups.getById(positiveId)
-
- group?.let { append(it) }
- }
- return group
- }
-
- @WorkerThread
- fun getMessageById(id: Int): VKMessage? {
- return AppGlobal.database.messages.getById(id)
- }
-
- @WorkerThread
- fun getMessagesByPeerId(peerId: Int): List {
- return AppGlobal.database.messages.getByPeerId(peerId)
- }
-
- @WorkerThread
- fun getMessages(): List {
- return AppGlobal.database.messages.getAll()
- }
-
- @WorkerThread
- fun getConversationById(id: Int): VKConversation? {
- return AppGlobal.database.conversations.getById(id)
- }
-
- @WorkerThread
- fun getConversations(): List {
- return AppGlobal.database.conversations.getAll()
- }
-
- @WorkerThread
- fun getFriends(userId: Int): List {
- return AppGlobal.database.friends.getByUserId(userId)
- }
-
- fun appendUsers(users: Collection) {
- for (user in users) {
- append(user)
- }
- }
-
- fun appendGroups(groups: Collection) {
- for (group in groups) {
- append(group)
- }
- }
-
- fun append(value: VKGroup) {
- groups.append(value.groupId, value)
- }
-
- fun append(value: VKUser) {
- users.append(value.userId, value)
- }
-
- @WorkerThread
- fun put(value: VKUser) {
- append(value)
-
- AppGlobal.database.users.insert(value)
- }
-
- @WorkerThread
- fun putUsers(users: List) {
- appendUsers(users)
-
- AppGlobal.database.users.insert(users)
- }
-
- @WorkerThread
- fun put(value: VKFriend) {
- AppGlobal.database.friends.insert(value)
- }
-
- @WorkerThread
- fun putFriends(friends: List) {
- AppGlobal.database.friends.insert(friends)
- }
-
- @WorkerThread
- fun put(value: VKMessage) {
- AppGlobal.database.messages.insert(value)
- }
-
- @WorkerThread
- fun putMessages(messages: List) {
- AppGlobal.database.messages.insert(messages)
- }
-
- @WorkerThread
- fun put(value: VKGroup) {
- append(value)
-
- AppGlobal.database.groups.insert(value)
- }
-
- @WorkerThread
- fun putGroups(groups: List) {
- appendGroups(groups)
-
- AppGlobal.database.groups.insert(groups)
- }
-
- @WorkerThread
- fun put(value: VKConversation) {
- AppGlobal.database.conversations.insert(value)
- }
-
- @WorkerThread
- fun putConversations(conversations: List) {
- AppGlobal.database.conversations.insert(conversations)
- }
-
- @WorkerThread
- fun deleteMessage(messageId: Int, safe: Boolean = true) {
- if (safe) {
- AppGlobal.database.messages.getById(messageId) ?: return
- }
-
- AppGlobal.database.messages.deleteById(messageId)
- }
-
- @WorkerThread
- fun deleteConversation(conversationId: Int, safe: Boolean = true) {
- if (safe) {
- AppGlobal.database.conversations.getById(conversationId) ?: return
- }
-
- AppGlobal.database.conversations.deleteById(conversationId)
- }
-
- @WorkerThread
- fun edit(message: VKMessage?, safe: Boolean = true) {
- message ?: return
-
- if (safe) {
- AppGlobal.database.messages.getById(message.messageId) ?: return
- }
-
- AppGlobal.database.messages.update(message)
- }
-
- fun clear() {
- users.clear()
- groups.clear()
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/database/QueryBuilder.kt b/app/src/main/java/com/meloda/fast/database/QueryBuilder.kt
new file mode 100644
index 00000000..8ca84781
--- /dev/null
+++ b/app/src/main/java/com/meloda/fast/database/QueryBuilder.kt
@@ -0,0 +1,71 @@
+package com.meloda.fast.database
+
+import android.database.Cursor
+import android.database.sqlite.SQLiteDatabase
+
+
+class QueryBuilder private constructor() {
+
+ companion object {
+ fun query(): QueryBuilder {
+ return QueryBuilder()
+ }
+ }
+
+ private val builder: StringBuilder = StringBuilder()
+
+ fun select(column: String): QueryBuilder {
+ builder.append("SELECT ")
+ .append(column)
+ .append(" ")
+ return this
+ }
+
+ fun from(table: String): QueryBuilder {
+ builder.append("FROM ")
+ .append(table)
+ .append(" ")
+ return this
+ }
+
+
+ fun where(clause: String): QueryBuilder {
+ builder.append("WHERE ")
+ .append(clause)
+ .append(" ")
+ return this
+ }
+
+ fun leftJoin(table: String): QueryBuilder {
+ builder.append("LEFT JOIN ")
+ .append(table)
+ .append(" ")
+ return this
+ }
+
+ fun on(where: String): QueryBuilder {
+ builder.append("ON ")
+ .append(where)
+ .append(" ")
+ return this
+ }
+
+ fun and(): QueryBuilder {
+ builder.append("AND ")
+ return this
+ }
+
+ fun or(): QueryBuilder {
+ builder.append("OR ")
+ return this
+ }
+
+ fun asCursor(db: SQLiteDatabase): Cursor {
+ return db.rawQuery(toString(), null)
+ }
+
+ override fun toString(): String {
+ return builder.toString().trim()
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/database/base/Storage.kt b/app/src/main/java/com/meloda/fast/database/base/Storage.kt
new file mode 100644
index 00000000..250cc1c6
--- /dev/null
+++ b/app/src/main/java/com/meloda/fast/database/base/Storage.kt
@@ -0,0 +1,32 @@
+package com.meloda.fast.database.base
+
+import android.content.ContentValues
+import android.database.Cursor
+import android.os.Bundle
+import androidx.annotation.WorkerThread
+import com.meloda.fast.common.AppGlobal
+
+abstract class Storage {
+
+ abstract val tag: String
+
+ protected var database = AppGlobal.database
+
+ @WorkerThread
+ abstract fun getAllValues(): ArrayList
+
+ @WorkerThread
+ abstract fun insertValues(values: ArrayList, params: Bundle? = null)
+
+ @WorkerThread
+ fun insertValue(value: T, params: Bundle? = null) {
+ insertValues(arrayListOf(value), params)
+ }
+
+ @WorkerThread
+ abstract fun cacheValue(values: ContentValues, value: T, params: Bundle? = null)
+
+ @WorkerThread
+ abstract fun parseValue(cursor: Cursor): T
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/database/dao/ConversationsDao.kt b/app/src/main/java/com/meloda/fast/database/dao/ConversationsDao.kt
deleted file mode 100644
index 91e4507f..00000000
--- a/app/src/main/java/com/meloda/fast/database/dao/ConversationsDao.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.meloda.fast.database.dao
-
-import androidx.room.*
-import com.meloda.fast.api.model.VKConversation
-
-@Dao
-interface ConversationsDao {
-
- @Query("SELECT * FROM conversations")
- fun getAll(): List
-
- @Query("SELECT * FROM conversations WHERE conversationId = :id")
- fun getById(id: Int): VKConversation?
-
- @Insert(onConflict = OnConflictStrategy.REPLACE)
- fun insert(item: VKConversation)
-
- @Insert(onConflict = OnConflictStrategy.REPLACE)
- fun insert(items: List)
-
- @Update
- fun update(item: VKConversation)
-
- @Update
- fun update(items: List)
-
- @Delete
- fun delete(item: VKConversation)
-
- @Delete
- fun delete(items: List)
-
- @Query("DELETE FROM conversations WHERE conversationId = :id")
- fun deleteById(id: Int)
-
- @Query("DELETE FROM conversations")
- fun clear()
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/database/dao/FriendsDao.kt b/app/src/main/java/com/meloda/fast/database/dao/FriendsDao.kt
deleted file mode 100644
index 52aee5a4..00000000
--- a/app/src/main/java/com/meloda/fast/database/dao/FriendsDao.kt
+++ /dev/null
@@ -1,41 +0,0 @@
-package com.meloda.fast.database.dao
-
-import androidx.room.*
-import com.meloda.fast.api.model.VKFriend
-
-@Dao
-interface FriendsDao {
-
- @Query("SELECT * FROM friends")
- fun getAll(): List
-
- @Query("SELECT * FROM friends WHERE userId = :id")
- fun getById(id: Int): VKFriend?
-
- @Insert(onConflict = OnConflictStrategy.REPLACE)
- fun insert(item: VKFriend)
-
- @Insert(onConflict = OnConflictStrategy.REPLACE)
- fun insert(items: List)
-
- @Update
- fun update(item: VKFriend)
-
- @Update
- fun update(items: List)
-
- @Delete
- fun delete(item: VKFriend)
-
- @Delete
- fun delete(items: List)
-
- @Query("DELETE FROM friends WHERE userId = :id")
- fun deleteById(id: Int)
-
- @Query("DELETE FROM friends")
- fun clear()
-
- @Query("SELECT * FROM friends WHERE userId = :id")
- fun getByUserId(id: Int): List
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/database/dao/GroupsDao.kt b/app/src/main/java/com/meloda/fast/database/dao/GroupsDao.kt
deleted file mode 100644
index 52e4056a..00000000
--- a/app/src/main/java/com/meloda/fast/database/dao/GroupsDao.kt
+++ /dev/null
@@ -1,37 +0,0 @@
-package com.meloda.fast.database.dao
-
-import androidx.room.*
-import com.meloda.fast.api.model.VKGroup
-
-@Dao
-interface GroupsDao {
- @Query("SELECT * FROM groups")
- fun getAll(): List
-
- @Query("SELECT * FROM groups WHERE groupId = :id")
- fun getById(id: Int): VKGroup?
-
- @Insert(onConflict = OnConflictStrategy.REPLACE)
- fun insert(item: VKGroup)
-
- @Insert(onConflict = OnConflictStrategy.REPLACE)
- fun insert(items: List)
-
- @Update
- fun update(item: VKGroup)
-
- @Update
- fun update(items: List)
-
- @Delete
- fun delete(item: VKGroup)
-
- @Delete
- fun delete(items: List)
-
- @Query("DELETE FROM groups WHERE groupId = :id")
- fun deleteById(id: Int)
-
- @Query("DELETE FROM groups")
- fun clear()
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/database/dao/MessagesDao.kt b/app/src/main/java/com/meloda/fast/database/dao/MessagesDao.kt
deleted file mode 100644
index e2163c53..00000000
--- a/app/src/main/java/com/meloda/fast/database/dao/MessagesDao.kt
+++ /dev/null
@@ -1,41 +0,0 @@
-package com.meloda.fast.database.dao
-
-import androidx.room.*
-import com.meloda.fast.api.model.VKMessage
-
-@Dao
-interface MessagesDao {
-
- @Query("SELECT * FROM messages")
- fun getAll(): List
-
- @Query("SELECT * FROM messages WHERE messageId = :id")
- fun getById(id: Int): VKMessage?
-
- @Insert(onConflict = OnConflictStrategy.REPLACE)
- fun insert(item: VKMessage)
-
- @Insert(onConflict = OnConflictStrategy.REPLACE)
- fun insert(items: List)
-
- @Update
- fun update(item: VKMessage)
-
- @Update
- fun update(items: List)
-
- @Delete
- fun delete(item: VKMessage)
-
- @Delete
- fun delete(items: List)
-
- @Query("DELETE FROM messages WHERE messageId = :id")
- fun deleteById(id: Int)
-
- @Query("DELETE FROM messages")
- fun clear()
-
- @Query("SELECT * FROM messages WHERE peerId = :peerId")
- fun getByPeerId(peerId: Int): List
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/database/dao/UsersDao.kt b/app/src/main/java/com/meloda/fast/database/dao/UsersDao.kt
deleted file mode 100644
index 21798f51..00000000
--- a/app/src/main/java/com/meloda/fast/database/dao/UsersDao.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.meloda.fast.database.dao
-
-import androidx.room.*
-import com.meloda.fast.api.model.VKUser
-
-@Dao
-interface UsersDao {
-
- @Query("SELECT * FROM users")
- fun getAll(): List
-
- @Query("SELECT * FROM users WHERE userId = :id")
- fun getById(id: Int): VKUser?
-
- @Insert(onConflict = OnConflictStrategy.REPLACE)
- fun insert(item: VKUser)
-
- @Insert(onConflict = OnConflictStrategy.REPLACE)
- fun insert(items: List)
-
- @Update
- fun update(item: VKUser)
-
- @Update
- fun update(items: List)
-
- @Delete
- fun delete(item: VKUser)
-
- @Delete
- fun delete(items: List)
-
- @Query("DELETE FROM users WHERE userId = :id")
- fun deleteById(id: Int)
-
- @Query("DELETE FROM users")
- fun clear()
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/database/dao/converters/ArrayListToByteArrayConverter.kt b/app/src/main/java/com/meloda/fast/database/dao/converters/ArrayListToByteArrayConverter.kt
deleted file mode 100644
index 6207e969..00000000
--- a/app/src/main/java/com/meloda/fast/database/dao/converters/ArrayListToByteArrayConverter.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.meloda.fast.database.dao.converters
-
-import androidx.room.TypeConverter
-import com.meloda.fast.api.model.VKModel
-import com.meloda.fast.extensions.ArrayExtensions.isNullOrEmpty
-import com.meloda.fast.util.Utils
-
-@Suppress("UNCHECKED_CAST")
-class ArrayListToByteArrayConverter {
-
- @TypeConverter
- fun toForwarded(data: ByteArray?): ArrayList {
- return if (data.isNullOrEmpty()) arrayListOf() else {
- val deserializedData = Utils.deserialize(data)
- if (deserializedData == null) arrayListOf() else deserializedData as ArrayList
- }
- }
-
- @TypeConverter
- fun fromForwarded(forwarded: List): ByteArray {
- return Utils.serialize(forwarded) ?: return byteArrayOf()
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/database/dao/converters/ForwardedConverter.kt b/app/src/main/java/com/meloda/fast/database/dao/converters/ForwardedConverter.kt
deleted file mode 100644
index 59380660..00000000
--- a/app/src/main/java/com/meloda/fast/database/dao/converters/ForwardedConverter.kt
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.meloda.fast.database.dao.converters
-
-import androidx.room.TypeConverter
-import com.meloda.fast.api.model.VKMessage
-import com.meloda.fast.extensions.ArrayExtensions.isNullOrEmpty
-import com.meloda.fast.util.Utils
-import java.util.*
-
-@Suppress("UNCHECKED_CAST")
-class ForwardedConverter {
-
- @TypeConverter
- fun toForwarded(data: ByteArray?): ArrayList {
- return if (data.isNullOrEmpty()) arrayListOf() else {
- val deserializedData = Utils.deserialize(data)
- if (deserializedData == null) arrayListOf() else deserializedData as ArrayList
- }
- }
-
- @TypeConverter
- fun fromForwarded(forwarded: List): ByteArray {
- return Utils.serialize(forwarded) ?: return byteArrayOf()
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/database/storage/ChatsStorage.kt b/app/src/main/java/com/meloda/fast/database/storage/ChatsStorage.kt
new file mode 100644
index 00000000..4d906eed
--- /dev/null
+++ b/app/src/main/java/com/meloda/fast/database/storage/ChatsStorage.kt
@@ -0,0 +1,141 @@
+package com.meloda.fast.database.storage
+
+import android.content.ContentValues
+import android.database.Cursor
+import android.os.Bundle
+import android.util.Log
+import androidx.annotation.WorkerThread
+import com.meloda.fast.database.CacheStorage
+import com.meloda.fast.database.CacheStorage.messagesStorage
+import com.meloda.fast.database.DatabaseKeys.CHAT_STATE
+import com.meloda.fast.database.DatabaseKeys.CONVERSATION_ID
+import com.meloda.fast.database.DatabaseKeys.IN_READ_MESSAGE_ID
+import com.meloda.fast.database.DatabaseKeys.IS_ALLOWED
+import com.meloda.fast.database.DatabaseKeys.IS_GROUP_CHANNEL
+import com.meloda.fast.database.DatabaseKeys.IS_NOTIFICATIONS_DISABLED
+import com.meloda.fast.database.DatabaseKeys.LAST_MESSAGE_ID
+import com.meloda.fast.database.DatabaseKeys.LOCAL_ID
+import com.meloda.fast.database.DatabaseKeys.MEMBERS_COUNT
+import com.meloda.fast.database.DatabaseKeys.NOT_ALLOWED_REASON
+import com.meloda.fast.database.DatabaseKeys.OUT_READ_MESSAGE_ID
+import com.meloda.fast.database.DatabaseKeys.PHOTOS
+import com.meloda.fast.database.DatabaseKeys.PINNED_MESSAGE_ID
+import com.meloda.fast.database.DatabaseKeys.TITLE
+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.vksdk.model.VKConversation
+import com.meloda.vksdk.util.VKUtil
+import org.json.JSONObject
+
+@WorkerThread
+class ChatsStorage : Storage() {
+
+ override val tag = "ChatsStorage"
+
+ override fun getAllValues(): ArrayList {
+ val cursor = CacheStorage.selectCursor(TABLE_CHATS)
+ val conversations = ArrayList()
+
+ while (cursor.moveToNext()) conversations.add(parseValue(cursor))
+
+ cursor.close()
+
+ return conversations
+ }
+
+ @WorkerThread
+ override fun insertValues(values: ArrayList, params: Bundle?) {
+ if (values.isEmpty()) return
+
+ database.beginTransaction()
+
+ val contentValues = ContentValues()
+
+ for (value in values) {
+ cacheValue(contentValues, value, params)
+
+ database.insert(TABLE_CHATS, null, contentValues)
+
+ contentValues.clear()
+ }
+
+ database.setTransactionSuccessful()
+ database.endTransaction()
+
+ Log.d(tag, "Successful cached chats")
+ }
+
+ @WorkerThread
+ override fun cacheValue(values: ContentValues, value: VKConversation, params: Bundle?) {
+ values.put(CONVERSATION_ID, value.id)
+ values.put(IS_ALLOWED, value.isAllowed)
+ values.put(NOT_ALLOWED_REASON, value.notAllowedReason.value)
+ values.put(IN_READ_MESSAGE_ID, value.inReadMessageId)
+ values.put(OUT_READ_MESSAGE_ID, value.outReadMessageId)
+ values.put(LAST_MESSAGE_ID, value.lastMessageId)
+ values.put(UNREAD_COUNT, value.unreadCount)
+ values.put(LOCAL_ID, value.localId)
+ values.put(IS_NOTIFICATIONS_DISABLED, value.notificationsEnabled)
+ values.put(MEMBERS_COUNT, value.membersCount)
+ values.put(TITLE, value.title)
+ values.put(IS_GROUP_CHANNEL, value.isGroupChannel)
+ values.put(TYPE, value.intType)
+ values.put(CHAT_STATE, value.intState)
+
+ values.put(
+ PHOTOS,
+ VKUtil.putPhotosToJson(
+ value.photo50,
+ value.photo100,
+ value.photo200
+ ).toString()
+ )
+
+ value.pinnedMessage?.let {
+ values.put(PINNED_MESSAGE_ID, it.id)
+ }
+ }
+
+ @WorkerThread
+ override fun parseValue(cursor: Cursor): VKConversation {
+ val conversation = VKConversation()
+
+ conversation.id = CacheStorage.getInt(cursor, CONVERSATION_ID)
+ conversation.isAllowed = CacheStorage.getInt(cursor, IS_ALLOWED) == 1
+ conversation.notAllowedReason = VKConversation.Reason.fromInt(
+ CacheStorage.getInt(cursor, NOT_ALLOWED_REASON)
+ )
+ conversation.inReadMessageId = CacheStorage.getInt(cursor, IN_READ_MESSAGE_ID)
+ conversation.outReadMessageId = CacheStorage.getInt(cursor, OUT_READ_MESSAGE_ID)
+ conversation.unreadCount = CacheStorage.getInt(cursor, UNREAD_COUNT)
+ conversation.localId = CacheStorage.getInt(cursor, LOCAL_ID)
+ conversation.notificationsEnabled =
+ CacheStorage.getInt(cursor, IS_NOTIFICATIONS_DISABLED) == 1
+ conversation.membersCount = CacheStorage.getInt(cursor, MEMBERS_COUNT)
+ conversation.title = CacheStorage.getString(cursor, TITLE)
+ conversation.isGroupChannel = CacheStorage.getInt(cursor, IS_GROUP_CHANNEL) == 1
+
+ val pinnedMessageId = CacheStorage.getInt(cursor, PINNED_MESSAGE_ID)
+ if (pinnedMessageId != -1) {
+ val pinnedMessage = messagesStorage.getMessageById(pinnedMessageId)
+ if (pinnedMessage != null) conversation.pinnedMessage = pinnedMessage
+ }
+
+ conversation.intType = CacheStorage.getInt(cursor, TYPE)
+ conversation.intState = CacheStorage.getInt(cursor, CHAT_STATE)
+
+ conversation.lastMessageId = CacheStorage.getInt(cursor, LAST_MESSAGE_ID)
+ val lastMessage = messagesStorage.getMessageById(conversation.lastMessageId)
+ if (lastMessage != null) conversation.lastMessage = lastMessage
+
+ val photos = VKUtil.parseJsonPhotos(JSONObject(CacheStorage.getString(cursor, PHOTOS)))
+ conversation.photo50 = photos[0]
+ conversation.photo100 = photos[1]
+ conversation.photo200 = photos[2]
+
+ return conversation
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/database/storage/GroupsStorage.kt b/app/src/main/java/com/meloda/fast/database/storage/GroupsStorage.kt
new file mode 100644
index 00000000..93810b28
--- /dev/null
+++ b/app/src/main/java/com/meloda/fast/database/storage/GroupsStorage.kt
@@ -0,0 +1,111 @@
+package com.meloda.fast.database.storage
+
+import android.content.ContentValues
+import android.database.Cursor
+import android.os.Bundle
+import android.util.Log
+import androidx.annotation.WorkerThread
+import com.meloda.fast.database.CacheStorage
+import com.meloda.fast.database.CacheStorage.getInt
+import com.meloda.fast.database.CacheStorage.getString
+import com.meloda.fast.database.DatabaseKeys.DEACTIVATED
+import com.meloda.fast.database.DatabaseKeys.GROUP_ID
+import com.meloda.fast.database.DatabaseKeys.IS_CLOSED
+import com.meloda.fast.database.DatabaseKeys.NAME
+import com.meloda.fast.database.DatabaseKeys.PHOTOS
+import com.meloda.fast.database.DatabaseKeys.SCREEN_NAME
+import com.meloda.fast.database.DatabaseKeys.TYPE
+import com.meloda.fast.database.DatabaseUtils.TABLE_GROUPS
+import com.meloda.fast.database.base.Storage
+import com.meloda.vksdk.model.VKGroup
+import com.meloda.vksdk.util.VKUtil
+import org.json.JSONObject
+
+class GroupsStorage : Storage() {
+
+ override val tag = "GroupsStorage"
+
+ @WorkerThread
+ fun getGroups(ids: IntArray): ArrayList {
+ val cursor = CacheStorage.selectCursor(TABLE_GROUPS, GROUP_ID, ids)
+
+ val groups = ArrayList(cursor.count)
+ while (cursor.moveToNext()) groups.add(parseValue(cursor))
+
+ cursor.close()
+ return groups
+ }
+
+ @WorkerThread
+ fun getGroup(userId: Int): VKGroup? {
+ val group = getGroups(intArrayOf(userId))
+
+ return if (group.isNotEmpty()) group[0] else null
+ }
+
+ override fun getAllValues(): ArrayList {
+ val cursor = CacheStorage.selectCursor(TABLE_GROUPS)
+ val groups = ArrayList()
+
+ while (cursor.moveToNext()) groups.add(parseValue(cursor))
+
+ cursor.close()
+
+ return groups
+ }
+
+ override fun insertValues(values: ArrayList, params: Bundle?) {
+ if (values.isEmpty()) return
+
+ database.beginTransaction()
+
+ val contentValues = ContentValues()
+
+ for (value in values) {
+ cacheValue(contentValues, value, params)
+
+ database.insert(TABLE_GROUPS, null, contentValues)
+
+ contentValues.clear()
+ }
+
+ database.setTransactionSuccessful()
+ database.endTransaction()
+
+ Log.d(tag, "Successful cached groups")
+ }
+
+ override fun cacheValue(values: ContentValues, value: VKGroup, params: Bundle?) {
+ values.put(GROUP_ID, value.id)
+ values.put(NAME, value.name)
+ values.put(SCREEN_NAME, value.screenName)
+ values.put(IS_CLOSED, value.isClosed)
+ values.put(DEACTIVATED, value.deactivated)
+ values.put(TYPE, value.type.value)
+
+ val photos =
+ VKUtil.putPhotosToJson(value.photo50, value.photo100, value.photo200).toString()
+
+ values.put(PHOTOS, photos)
+ }
+
+ override fun parseValue(cursor: Cursor): VKGroup {
+ val group = VKGroup()
+
+ group.id = getInt(cursor, GROUP_ID)
+ group.name = getString(cursor, NAME)
+ group.screenName = getString(cursor, SCREEN_NAME)
+ group.isClosed = getInt(cursor, IS_CLOSED) == 1
+ group.deactivated = getString(cursor, DEACTIVATED)
+ group.type = VKGroup.Type.fromString(getString(cursor, TYPE))
+
+ val photos = VKUtil.parseJsonPhotos(JSONObject(getString(cursor, PHOTOS)))
+
+ group.photo50 = photos[0]
+ group.photo100 = photos[1]
+ group.photo200 = photos[2]
+
+ return group
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/database/storage/MessagesStorage.kt b/app/src/main/java/com/meloda/fast/database/storage/MessagesStorage.kt
new file mode 100644
index 00000000..a9203e61
--- /dev/null
+++ b/app/src/main/java/com/meloda/fast/database/storage/MessagesStorage.kt
@@ -0,0 +1,178 @@
+package com.meloda.fast.database.storage
+
+import android.content.ContentValues
+import android.database.Cursor
+import android.os.Bundle
+import android.util.Log
+import androidx.annotation.WorkerThread
+import com.meloda.fast.database.CacheStorage
+import com.meloda.fast.database.CacheStorage.selectCursor
+import com.meloda.fast.database.DatabaseKeys.ACTION
+import com.meloda.fast.database.DatabaseKeys.ATTACHMENTS
+import com.meloda.fast.database.DatabaseKeys.CONVERSATION_MESSAGE_ID
+import com.meloda.fast.database.DatabaseKeys.DATE
+import com.meloda.fast.database.DatabaseKeys.EDIT_TIME
+import com.meloda.fast.database.DatabaseKeys.FROM_ID
+import com.meloda.fast.database.DatabaseKeys.FWD_MESSAGES
+import com.meloda.fast.database.DatabaseKeys.IS_OUT
+import com.meloda.fast.database.DatabaseKeys.MESSAGE_ID
+import com.meloda.fast.database.DatabaseKeys.PEER_ID
+import com.meloda.fast.database.DatabaseKeys.RANDOM_ID
+import com.meloda.fast.database.DatabaseKeys.REPLY_MESSAGE_ID
+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.vksdk.model.VKMessage
+import com.meloda.vksdk.model.VKMessageAction
+import com.meloda.vksdk.model.VKModel
+import java.util.stream.Collectors
+
+@WorkerThread
+@Suppress("UNCHECKED_CAST")
+class MessagesStorage : Storage() {
+
+ override val tag = "MessagesStorage"
+
+ @WorkerThread
+ fun getMessagesHistory(peerId: Int): ArrayList {
+ val cursor = CacheStorage.selectCursor(TABLE_MESSAGES, PEER_ID, peerId)
+
+ val messages = ArrayList(cursor.count)
+ while (cursor.moveToNext()) messages.add(parseValue(cursor))
+
+ cursor.close()
+
+ return messages
+ }
+
+ @WorkerThread
+ fun getMessageById(messageId: Int): VKMessage? {
+ val cursor = CacheStorage.selectCursor(TABLE_MESSAGES, MESSAGE_ID, messageId)
+
+ if (cursor.moveToFirst()) {
+ val message = parseValue(cursor)
+ cursor.close()
+
+ return message
+ }
+
+ return null
+ }
+
+ override fun getAllValues(): ArrayList {
+ val cursor = selectCursor(TABLE_MESSAGES)
+ val messages = ArrayList()
+
+ while (cursor.moveToNext()) messages.add(parseValue(cursor))
+
+ cursor.close()
+
+ return messages
+ }
+
+ @WorkerThread
+ override fun insertValues(values: ArrayList, params: Bundle?) {
+ if (values.isEmpty()) return
+
+ database.beginTransaction()
+
+ val contentValues = ContentValues()
+
+ for (value in values) {
+ cacheValue(contentValues, value)
+
+ database.insert(TABLE_MESSAGES, null, contentValues)
+
+ contentValues.clear()
+ }
+
+ database.setTransactionSuccessful()
+ database.endTransaction()
+
+ Log.d(tag, "Successful cached messages")
+ }
+
+ @WorkerThread
+ override fun cacheValue(values: ContentValues, value: VKMessage, params: Bundle?) {
+ values.put(MESSAGE_ID, value.id)
+ values.put(DATE, value.date)
+ values.put(PEER_ID, value.peerId)
+ values.put(FROM_ID, value.fromId)
+ values.put(EDIT_TIME, value.editTime)
+ values.put(TEXT, value.text)
+ values.put(RANDOM_ID, value.randomId)
+ values.put(CONVERSATION_MESSAGE_ID, value.conversationMessageId)
+
+ value.replyMessage?.let {
+ values.put(REPLY_MESSAGE_ID, it.id)
+ }
+
+ value.action?.let {
+ values.put(ACTION, Utils.serialize(it))
+ }
+
+ value.attachments.let {
+ if (it.isNotEmpty()) {
+ values.put(ATTACHMENTS, Utils.serialize(it))
+ }
+ }
+
+ value.fwdMessages.let {
+ if (it.isNotEmpty()) {
+ val ids = arrayListOf()
+ it.forEach { message -> ids.add(message.id.toString()) }
+
+ ids.stream().collect(Collectors.joining(",")).let { str ->
+ values.put(FWD_MESSAGES, str)
+ }
+ }
+ }
+ }
+
+ @WorkerThread
+ override fun parseValue(cursor: Cursor): VKMessage {
+ val message = VKMessage()
+
+ message.id = CacheStorage.getInt(cursor, MESSAGE_ID)
+ message.date = CacheStorage.getInt(cursor, DATE)
+ message.peerId = CacheStorage.getInt(cursor, PEER_ID)
+ message.fromId = CacheStorage.getInt(cursor, FROM_ID)
+ message.editTime = CacheStorage.getInt(cursor, EDIT_TIME)
+ message.isOut = CacheStorage.getInt(cursor, IS_OUT) == 1
+ message.text = CacheStorage.getString(cursor, TEXT)
+ message.randomId = CacheStorage.getInt(cursor, RANDOM_ID)
+ message.conversationMessageId = CacheStorage.getInt(cursor, CONVERSATION_MESSAGE_ID)
+
+ val blobAttachments = Utils.deserialize(CacheStorage.getBlob(cursor, ATTACHMENTS))
+ if (blobAttachments != null) message.attachments = blobAttachments as ArrayList
+ else message.attachments = arrayListOf()
+
+ val replyMessageId = CacheStorage.getInt(cursor, REPLY_MESSAGE_ID)
+ val replyMessage = getMessageById(replyMessageId)
+ if (replyMessage != null) message.replyMessage = replyMessage
+
+ val blobAction = Utils.deserialize(CacheStorage.getBlob(cursor, ACTION))
+ if (blobAction != null) message.action = blobAction as VKMessageAction
+
+ val stringFwdMessages = CacheStorage.getString(cursor, FWD_MESSAGES)
+ if (stringFwdMessages != null) {
+ val split = stringFwdMessages.split(',')
+
+ val ids = arrayListOf()
+ for (s in split) ids.add(s.toInt())
+
+ val fwdMessages = arrayListOf()
+
+ ids.forEach {
+ val fwdMessage = getMessageById(it)
+ if (fwdMessage != null) fwdMessages.add(fwdMessage)
+ }
+
+ message.fwdMessages = fwdMessages
+ } else message.fwdMessages = arrayListOf()
+
+ return message
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/meloda/fast/database/storage/UsersStorage.kt b/app/src/main/java/com/meloda/fast/database/storage/UsersStorage.kt
new file mode 100644
index 00000000..f2296c7e
--- /dev/null
+++ b/app/src/main/java/com/meloda/fast/database/storage/UsersStorage.kt
@@ -0,0 +1,172 @@
+package com.meloda.fast.database.storage
+
+import android.content.ContentValues
+import android.database.Cursor
+import android.os.Bundle
+import android.util.Log
+import androidx.annotation.WorkerThread
+import com.meloda.fast.UserConfig
+import com.meloda.fast.database.CacheStorage
+import com.meloda.fast.database.CacheStorage.selectCursor
+import com.meloda.fast.database.DatabaseKeys.DEACTIVATED
+import com.meloda.fast.database.DatabaseKeys.FIRST_NAME
+import com.meloda.fast.database.DatabaseKeys.FRIEND_ID
+import com.meloda.fast.database.DatabaseKeys.GENDER
+import com.meloda.fast.database.DatabaseKeys.IS_ONLINE
+import com.meloda.fast.database.DatabaseKeys.IS_ONLINE_MOBILE
+import com.meloda.fast.database.DatabaseKeys.LAST_NAME
+import com.meloda.fast.database.DatabaseKeys.LAST_SEEN
+import com.meloda.fast.database.DatabaseKeys.PHOTOS
+import com.meloda.fast.database.DatabaseKeys.SCREEN_NAME
+import com.meloda.fast.database.DatabaseKeys.SORT_ID
+import com.meloda.fast.database.DatabaseKeys.STATUS
+import com.meloda.fast.database.DatabaseKeys.USER_ID
+import com.meloda.fast.database.DatabaseUtils.TABLE_FRIENDS
+import com.meloda.fast.database.DatabaseUtils.TABLE_USERS
+import com.meloda.fast.database.QueryBuilder
+import com.meloda.fast.database.base.Storage
+import com.meloda.vksdk.model.VKUser
+import com.meloda.vksdk.util.VKUtil
+import org.json.JSONObject
+
+@WorkerThread
+class UsersStorage : Storage() {
+
+ override val tag = "UsersStorage"
+
+ @WorkerThread
+ fun getUsers(ids: IntArray): ArrayList {
+ val cursor = CacheStorage.selectCursor(TABLE_USERS, USER_ID, ids)
+
+ val users = ArrayList