Release 0.2.0 (#150)

Release Notes

* Bumped haze, agp, and guava dependencies
* Implemented ordering functionality for friends list
* Added scroll to top feature in friends and conversations screens
* Improved messages handling
* Fixed coloring issues
* Cache improvements
* Implemented logout functionality
* Implemented new authorization flow (no auto-token re-request)
* Added support for sticker pack preview attachments
* Bump LongPoll to version 19
* Markdown support for messages bubbles
* Adjust app name font size based on screen width

---------

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This commit is contained in:
2025-04-04 21:47:05 +03:00
committed by GitHub
parent 0eb3146428
commit 82fb78e9ea
279 changed files with 9171 additions and 4517 deletions
@@ -2,11 +2,11 @@
"formatVersion": 1,
"database": {
"version": 2,
"identityHash": "3ebd234270e36902d3d461af38664869",
"identityHash": "ca007bca2ab4a9b901662792042770ad",
"entities": [
{
"tableName": "accounts",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`userId` INTEGER NOT NULL, `accessToken` TEXT NOT NULL, `fastToken` TEXT, `trustedHash` TEXT, PRIMARY KEY(`userId`))",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`userId` INTEGER NOT NULL, `accessToken` TEXT NOT NULL, `fastToken` TEXT, `trustedHash` TEXT, `exchangeToken` TEXT, PRIMARY KEY(`userId`))",
"fields": [
{
"fieldPath": "userId",
@@ -31,6 +31,12 @@
"columnName": "trustedHash",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "exchangeToken",
"columnName": "exchangeToken",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
@@ -46,7 +52,7 @@
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '3ebd234270e36902d3d461af38664869')"
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'ca007bca2ab4a9b901662792042770ad')"
]
}
}
@@ -7,7 +7,7 @@ import dev.meloda.fast.model.database.AccountEntity
@Database(
entities = [AccountEntity::class],
version = 2
version = 3
)
abstract class AccountsDatabase : RoomDatabase() {
abstract fun accountDao(): AccountDao
@@ -6,7 +6,7 @@ import androidx.room.TypeConverters
import dev.meloda.fast.database.dao.ConversationDao
import dev.meloda.fast.database.dao.GroupDao
import dev.meloda.fast.database.dao.MessageDao
import dev.meloda.fast.database.dao.UsersDao
import dev.meloda.fast.database.dao.UserDao
import dev.meloda.fast.database.typeconverters.Converters
import dev.meloda.fast.model.database.VkConversationEntity
import dev.meloda.fast.model.database.VkGroupEntity
@@ -21,11 +21,11 @@ import dev.meloda.fast.model.database.VkUserEntity
VkConversationEntity::class
],
version = 7
version = 10
)
@TypeConverters(Converters::class)
abstract class CacheDatabase : RoomDatabase() {
abstract fun userDao(): UsersDao
abstract fun userDao(): UserDao
abstract fun groupDao(): GroupDao
abstract fun messageDao(): MessageDao
abstract fun conversationDao(): ConversationDao
@@ -11,8 +11,8 @@ abstract class AccountDao : EntityDao<AccountEntity> {
abstract suspend fun getAll(): List<AccountEntity>
@Query("SELECT * FROM accounts WHERE userId = :userId")
abstract suspend fun getById(userId: Int): AccountEntity?
abstract suspend fun getById(userId: Long): AccountEntity?
@Query("DELETE FROM accounts WHERE userId = :userId")
abstract suspend fun deleteById(userId: Int)
abstract suspend fun deleteById(userId: Long)
}
@@ -16,11 +16,11 @@ abstract class ConversationDao : EntityDao<VkConversationEntity> {
abstract suspend fun getAllByIds(ids: List<Int>): List<VkConversationEntity>
@Query("SELECT * FROM conversations WHERE id IS (:id)")
abstract suspend fun getById(id: Int): VkConversationEntity?
abstract suspend fun getById(id: Long): VkConversationEntity?
@Transaction
@Query("SELECT * FROM conversations WHERE id IS (:id)")
abstract suspend fun getByIdWithMessage(id: Int): ConversationWithMessage?
abstract suspend fun getByIdWithMessage(id: Long): ConversationWithMessage?
@Query("DELETE FROM conversations WHERE rowid IN (:ids)")
abstract suspend fun deleteByIds(ids: List<Int>): Int
@@ -11,13 +11,13 @@ abstract class MessageDao : EntityDao<VkMessageEntity> {
abstract suspend fun getAll(): List<VkMessageEntity>
@Query("SELECT * FROM messages WHERE peerId IS (:conversationId)")
abstract suspend fun getAll(conversationId: Int): List<VkMessageEntity>
abstract suspend fun getAll(conversationId: Long): List<VkMessageEntity>
@Query("SELECT * FROM messages WHERE id IN (:ids)")
abstract suspend fun getAllByIds(ids: List<Int>): List<VkMessageEntity>
@Query("SELECT * FROM messages WHERE id IS (:messageId)")
abstract suspend fun getById(messageId: Int): VkMessageEntity?
abstract suspend fun getById(messageId: Long): VkMessageEntity?
@Query("DELETE FROM messages WHERE id IN (:ids)")
abstract suspend fun deleteByIds(ids: List<Int>): Int
@@ -5,14 +5,14 @@ import androidx.room.Query
import dev.meloda.fast.model.database.VkUserEntity
@Dao
abstract class UsersDao : EntityDao<VkUserEntity> {
abstract class UserDao : EntityDao<VkUserEntity> {
@Query("SELECT * FROM users")
abstract suspend fun getAll(): List<VkUserEntity>
@Query("SELECT * FROM users WHERE id IN (:ids)")
abstract suspend fun getAllByIds(ids: List<Int>): List<VkUserEntity>
abstract suspend fun getAllByIds(ids: List<Long>): List<VkUserEntity>
@Query("DELETE FROM users WHERE id IN (:ids)")
abstract suspend fun deleteByIds(ids: List<Int>): Int
abstract suspend fun deleteByIds(ids: List<Long>): Int
}
@@ -2,17 +2,21 @@ package dev.meloda.fast.database.di
import androidx.room.Room
import dev.meloda.fast.database.AccountsDatabase
import dev.meloda.fast.database.CacheDatabase
import dev.meloda.fast.database.di.migration.migrationFrom2To3
import org.koin.core.scope.Scope
import org.koin.dsl.module
val databaseModule = module {
single {
Room.databaseBuilder(get(), AccountsDatabase::class.java, "accounts").build()
Room.databaseBuilder(get(), AccountsDatabase::class.java, "accounts")
.addMigrations(migrationFrom2To3)
.build()
}
single { get<AccountsDatabase>().accountDao() }
single {
Room.databaseBuilder(get(), dev.meloda.fast.database.CacheDatabase::class.java, "cache")
Room.databaseBuilder(get(), CacheDatabase::class.java, "cache")
.fallbackToDestructiveMigration()
.build()
}
@@ -22,4 +26,4 @@ val databaseModule = module {
single { cacheDB().conversationDao() }
}
private fun Scope.cacheDB(): dev.meloda.fast.database.CacheDatabase = get()
private fun Scope.cacheDB(): CacheDatabase = get()
@@ -0,0 +1,14 @@
package dev.meloda.fast.database.di.migration
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
val migrationFrom2To3 = object : Migration(
startVersion = 2,
endVersion = 3
) {
override fun migrate(db: SupportSQLiteDatabase) {
db.execSQL("ALTER TABLE accounts ADD COLUMN exchangeToken TEXT DEFAULT null")
}
}
@@ -13,6 +13,15 @@ class Converters {
.split(", ")
.mapNotNull(String::toIntOrNull)
@TypeConverter
fun longListToString(list: List<Long>): String = list.joinToString()
@TypeConverter
fun stringToLongList(string: String): List<Long> =
string
.split(", ")
.mapNotNull(String::toLongOrNull)
@TypeConverter
fun stringListToString(list: List<String>): String = list.joinToString()