Update API version (#147)

* Bump VK Api version to 5.238
* Implemented new authorization flow (at the moment, without auto re-requesting token)
* Add support for sticker pack preview attachments
* Bump LongPoll to version 19
* Improved messages handling
* Fixed coloring issues
* Cache improvements
* Archive screen with full functionality
* Recomposition fixes
* Markdown support for messages bubbles
* Adjust app name font size based on screen width
* Navigation related improvements
* Add logout functionality
This commit is contained in:
2025-04-04 20:43:59 +03:00
committed by GitHub
parent add67b6f8d
commit 89748b72ed
237 changed files with 4896 additions and 3289 deletions
@@ -17,7 +17,6 @@ import dev.meloda.fast.model.api.domain.VkAttachmentHistoryMessage
import dev.meloda.fast.network.VkErrorCode
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.update
interface ChatMaterialsViewModel {
val screenState: StateFlow<ChatMaterialsScreenState>
@@ -54,7 +53,7 @@ class ChatMaterialsViewModelImpl(
screenState.setValue { old ->
old.copy(
peerId = arguments.peerId,
conversationMessageId = arguments.conversationMessageId
cmId = arguments.conversationMessageId
)
}
@@ -85,7 +84,7 @@ class ChatMaterialsViewModelImpl(
count = LOAD_COUNT,
offset = offset,
attachmentTypes = listOf(materialType.toString()),
conversationMessageId = screenState.value.conversationMessageId
cmId = screenState.value.cmId
).listenValue(viewModelScope) { state ->
state.processState(
error = ::handleError,
@@ -100,11 +99,11 @@ class ChatMaterialsViewModelImpl(
val newState = screenState.value.copy(
isPaginationExhausted = paginationExhausted,
conversationMessageId = if (loadedMaterials.size + offset > 200) {
cmId = if (loadedMaterials.size + offset > 200) {
currentOffset.setValue { 0 }
loadedMaterials.lastOrNull()?.conversationMessageId ?: -1
} else {
screenState.value.conversationMessageId
screenState.value.cmId
}
)
@@ -9,8 +9,8 @@ data class ChatMaterialsScreenState(
val attachmentType: String,
val isPaginating: Boolean,
val isPaginationExhausted: Boolean,
val peerId: Int,
val conversationMessageId: Int
val peerId: Long,
val cmId: Long
) {
companion object {
@@ -21,7 +21,7 @@ data class ChatMaterialsScreenState(
isPaginating = false,
isPaginationExhausted = false,
peerId = -1,
conversationMessageId = -1
cmId = -1
)
}
}
@@ -1,16 +1,16 @@
package dev.meloda.fast.chatmaterials.model
sealed class UiChatMaterial(
open val conversationMessageId: Int
open val conversationMessageId: Long
) {
data class Photo(
override val conversationMessageId: Int,
override val conversationMessageId: Long,
val previewUrl: String
) : UiChatMaterial(conversationMessageId)
data class Video(
override val conversationMessageId: Int,
override val conversationMessageId: Long,
val previewUrl: String?,
val title: String,
val views: Int,
@@ -18,7 +18,7 @@ sealed class UiChatMaterial(
) : UiChatMaterial(conversationMessageId)
data class Audio(
override val conversationMessageId: Int,
override val conversationMessageId: Long,
val previewUrl: String?,
val title: String,
val artist: String,
@@ -26,7 +26,7 @@ sealed class UiChatMaterial(
) : UiChatMaterial(conversationMessageId)
data class File(
override val conversationMessageId: Int,
override val conversationMessageId: Long,
val previewUrl: String?,
val title: String,
val size: String,
@@ -34,7 +34,7 @@ sealed class UiChatMaterial(
) : UiChatMaterial(conversationMessageId)
data class Link(
override val conversationMessageId: Int,
override val conversationMessageId: Long,
val previewUrl: String?,
val title: String?,
val url: String,
@@ -10,8 +10,8 @@ import kotlinx.serialization.Serializable
@Serializable
data class ChatMaterials(
val peerId: Int,
val conversationMessageId: Int
val peerId: Long,
val conversationMessageId: Long
) {
companion object {
fun from(savedStateHandle: SavedStateHandle) =
@@ -31,7 +31,7 @@ fun NavGraphBuilder.chatMaterialsScreen(
}
}
fun NavController.navigateToChatMaterials(peerId: Int, conversationMessageId: Int) {
fun NavController.navigateToChatMaterials(peerId: Long, conversationMessageId: Long) {
this.navigate(
ChatMaterials(
peerId = peerId,
@@ -53,9 +53,9 @@ import dev.meloda.fast.model.BaseError
import dev.meloda.fast.ui.R
import dev.meloda.fast.ui.basic.ContentAlpha
import dev.meloda.fast.ui.basic.LocalContentAlpha
import dev.meloda.fast.ui.components.ErrorView
import dev.meloda.fast.ui.components.FullScreenLoader
import dev.meloda.fast.ui.components.NoItemsView
import dev.meloda.fast.ui.components.VkErrorView
import dev.meloda.fast.ui.theme.LocalHazeState
import dev.meloda.fast.ui.theme.LocalThemeConfig
import kotlinx.coroutines.Dispatchers
@@ -102,23 +102,7 @@ fun AudioMaterialsScreen(
when {
baseError != null -> {
when (baseError) {
is BaseError.SessionExpired -> {
ErrorView(
text = stringResource(UiR.string.session_expired),
buttonText = stringResource(UiR.string.action_log_out),
onButtonClick = onSessionExpiredLogOutButtonClicked
)
}
is BaseError.SimpleError -> {
ErrorView(
text = baseError.message,
buttonText = stringResource(UiR.string.try_again),
onButtonClick = onRefresh
)
}
}
VkErrorView(baseError = baseError)
}
screenState.isLoading && screenState.materials.isEmpty() -> FullScreenLoader()
@@ -63,9 +63,9 @@ import dev.meloda.fast.model.BaseError
import dev.meloda.fast.ui.R
import dev.meloda.fast.ui.basic.ContentAlpha
import dev.meloda.fast.ui.basic.LocalContentAlpha
import dev.meloda.fast.ui.components.ErrorView
import dev.meloda.fast.ui.components.FullScreenLoader
import dev.meloda.fast.ui.components.NoItemsView
import dev.meloda.fast.ui.components.VkErrorView
import dev.meloda.fast.ui.theme.LocalHazeState
import dev.meloda.fast.ui.theme.LocalThemeConfig
import kotlinx.coroutines.Dispatchers
@@ -111,23 +111,7 @@ fun FileMaterialsScreen(
when {
baseError != null -> {
when (baseError) {
is BaseError.SessionExpired -> {
ErrorView(
text = stringResource(R.string.session_expired),
buttonText = stringResource(R.string.action_log_out),
onButtonClick = onSessionExpiredLogOutButtonClicked
)
}
is BaseError.SimpleError -> {
ErrorView(
text = baseError.message,
buttonText = stringResource(R.string.try_again),
onButtonClick = onRefresh
)
}
}
VkErrorView(baseError = baseError)
}
screenState.isLoading && screenState.materials.isEmpty() -> FullScreenLoader()
@@ -63,9 +63,9 @@ import dev.meloda.fast.model.BaseError
import dev.meloda.fast.ui.R
import dev.meloda.fast.ui.basic.ContentAlpha
import dev.meloda.fast.ui.basic.LocalContentAlpha
import dev.meloda.fast.ui.components.ErrorView
import dev.meloda.fast.ui.components.FullScreenLoader
import dev.meloda.fast.ui.components.NoItemsView
import dev.meloda.fast.ui.components.VkErrorView
import dev.meloda.fast.ui.theme.LocalHazeState
import dev.meloda.fast.ui.theme.LocalThemeConfig
import kotlinx.coroutines.Dispatchers
@@ -111,23 +111,7 @@ fun LinkMaterialsScreen(
when {
baseError != null -> {
when (baseError) {
is BaseError.SessionExpired -> {
ErrorView(
text = stringResource(R.string.session_expired),
buttonText = stringResource(R.string.action_log_out),
onButtonClick = onSessionExpiredLogOutButtonClicked
)
}
is BaseError.SimpleError -> {
ErrorView(
text = baseError.message,
buttonText = stringResource(R.string.try_again),
onButtonClick = onRefresh
)
}
}
VkErrorView(baseError = baseError)
}
screenState.isLoading && screenState.materials.isEmpty() -> FullScreenLoader()
@@ -46,9 +46,9 @@ import dev.meloda.fast.chatmaterials.model.ChatMaterialsScreenState
import dev.meloda.fast.chatmaterials.model.UiChatMaterial
import dev.meloda.fast.model.BaseError
import dev.meloda.fast.ui.R
import dev.meloda.fast.ui.components.ErrorView
import dev.meloda.fast.ui.components.FullScreenLoader
import dev.meloda.fast.ui.components.NoItemsView
import dev.meloda.fast.ui.components.VkErrorView
import dev.meloda.fast.ui.theme.LocalHazeState
import dev.meloda.fast.ui.theme.LocalThemeConfig
import kotlinx.coroutines.Dispatchers
@@ -95,23 +95,7 @@ fun PhotoMaterialsScreen(
when {
baseError != null -> {
when (baseError) {
is BaseError.SessionExpired -> {
ErrorView(
text = stringResource(R.string.session_expired),
buttonText = stringResource(R.string.action_log_out),
onButtonClick = onSessionExpiredLogOutButtonClicked
)
}
is BaseError.SimpleError -> {
ErrorView(
text = baseError.message,
buttonText = stringResource(R.string.try_again),
onButtonClick = onRefresh
)
}
}
VkErrorView(baseError = baseError)
}
screenState.isLoading && screenState.materials.isEmpty() -> FullScreenLoader()
@@ -56,9 +56,9 @@ import dev.meloda.fast.model.BaseError
import dev.meloda.fast.ui.R
import dev.meloda.fast.ui.basic.ContentAlpha
import dev.meloda.fast.ui.basic.LocalContentAlpha
import dev.meloda.fast.ui.components.ErrorView
import dev.meloda.fast.ui.components.FullScreenLoader
import dev.meloda.fast.ui.components.NoItemsView
import dev.meloda.fast.ui.components.VkErrorView
import dev.meloda.fast.ui.theme.LocalHazeState
import dev.meloda.fast.ui.theme.LocalThemeConfig
import kotlinx.coroutines.Dispatchers
@@ -104,23 +104,7 @@ fun VideoMaterialsScreen(
when {
baseError != null -> {
when (baseError) {
is BaseError.SessionExpired -> {
ErrorView(
text = stringResource(R.string.session_expired),
buttonText = stringResource(R.string.action_log_out),
onButtonClick = onSessionExpiredLogOutButtonClicked
)
}
is BaseError.SimpleError -> {
ErrorView(
text = baseError.message,
buttonText = stringResource(R.string.try_again),
onButtonClick = onRefresh
)
}
}
VkErrorView(baseError = baseError)
}
screenState.isLoading && screenState.materials.isEmpty() -> FullScreenLoader()