ability to use more animations (experimental);

fix online friends loading;
conversation avatar in messages history screen;
test second tap on conversations item in bottom bar to scroll to top;
etc
This commit is contained in:
2024-12-17 20:51:02 +03:00
parent 85cda2065e
commit 6a69f28256
21 changed files with 299 additions and 85 deletions
@@ -1,8 +1,8 @@
package dev.meloda.fast.data.api.conversations
import com.slack.eithernet.ApiResult
import dev.meloda.fast.model.api.domain.VkConversation
import dev.meloda.fast.network.RestApiErrorDomain
import com.slack.eithernet.ApiResult
interface ConversationsRepository {
@@ -11,6 +11,10 @@ interface ConversationsRepository {
offset: Int?
): ApiResult<List<VkConversation>, RestApiErrorDomain>
suspend fun getConversationsById(
peerIds: List<Int>
): ApiResult<List<VkConversation>, RestApiErrorDomain>
suspend fun storeConversations(conversations: List<VkConversation>)
suspend fun delete(peerId: Int): ApiResult<Int, RestApiErrorDomain>
suspend fun pin(peerId: Int): ApiResult<Int, RestApiErrorDomain>
@@ -1,5 +1,6 @@
package dev.meloda.fast.data.api.conversations
import com.slack.eithernet.ApiResult
import dev.meloda.fast.common.VkConstants
import dev.meloda.fast.data.VkGroupsMap
import dev.meloda.fast.data.VkMemoryCache
@@ -19,7 +20,6 @@ import dev.meloda.fast.network.RestApiErrorDomain
import dev.meloda.fast.network.mapApiDefault
import dev.meloda.fast.network.mapApiResult
import dev.meloda.fast.network.service.conversations.ConversationsService
import com.slack.eithernet.ApiResult
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@@ -79,6 +79,45 @@ class ConversationsRepositoryImpl(
)
}
override suspend fun getConversationsById(
peerIds: List<Int>
): ApiResult<List<VkConversation>, RestApiErrorDomain> = withContext(Dispatchers.IO) {
val requestParams = mapOf(
"peer_ids" to peerIds.joinToString(separator = ","),
"extended" to "1",
"fields" to VkConstants.ALL_FIELDS
)
conversationsService.getConversationsById(requestParams).mapApiResult(
successMapper = { apiResponse ->
val response = apiResponse.requireResponse()
val profilesList = response.profiles.orEmpty().map(VkUserData::mapToDomain)
val groupsList = response.groups.orEmpty().map(VkGroupData::mapToDomain)
val contactsList = response.contacts.orEmpty().map(VkContactData::mapToDomain)
val usersMap = VkUsersMap.forUsers(profilesList)
val groupsMap = VkGroupsMap.forGroups(groupsList)
VkMemoryCache.appendUsers(profilesList)
VkMemoryCache.appendGroups(groupsList)
VkMemoryCache.appendContacts(contactsList)
response.items.map { item ->
item.asDomain().let { conversation ->
conversation.copy(
user = usersMap.conversationUser(conversation),
group = groupsMap.conversationGroup(conversation)
).also { VkMemoryCache[conversation.id] = it }
}
}
},
errorMapper = { error ->
error?.toDomain()
}
)
}
override suspend fun storeConversations(conversations: List<VkConversation>) {
conversationDao.insertAll(conversations.map(VkConversation::asEntity))
}
@@ -188,6 +188,13 @@ object AppSettings {
SettingsKeys.DEFAULT_USE_BLUR
)
set(value) = put(SettingsKeys.KEY_USE_BLUR, value)
var moreAnimations: Boolean
get() = get(
SettingsKeys.KEY_MORE_ANIMATIONS,
SettingsKeys.DEFAULT_MORE_ANIMATIONS
)
set(value) = put(SettingsKeys.KEY_MORE_ANIMATIONS, value)
}
object Debug {
@@ -42,15 +42,16 @@ object SettingsKeys {
const val KEY_DEBUG_PERFORM_CRASH = "debug_perform_crash"
const val KEY_DEBUG_SHOW_CRASH_ALERT = "debug_show_crash_alert"
const val KEY_DEBUG_HIDE_DEBUG_LIST = "debug_hide_debug_list"
const val KEY_ENABLE_ANIMATIONS_IN_MESSAGES = "debug_enable_animations_in_messages"
const val KEY_ENABLE_HAPTIC = "enable_haptic"
const val DEFAULT_ENABLE_HAPTIC = true
const val KEY_DEBUG_NETWORK_LOG_LEVEL = "debug_network_log_level"
const val DEFAULT_NETWORK_LOG_LEVEL = 0
const val KEY_USE_SYSTEM_FONT = "use_system_font"
const val DEFAULT_USE_SYSTEM_FONT = false
const val KEY_MORE_ANIMATIONS = "more_animations"
const val DEFAULT_MORE_ANIMATIONS = false
const val KEY_SHOW_DEBUG_CATEGORY = "show_debug_category"
const val ID_DMITRY = 37610580
}
@@ -0,0 +1,23 @@
package dev.meloda.fast.domain
import dev.meloda.fast.data.State
import dev.meloda.fast.data.api.conversations.ConversationsRepository
import dev.meloda.fast.data.mapToState
import dev.meloda.fast.model.api.domain.VkConversation
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
class LoadConversationsByIdUseCase(
private val conversationsRepository: ConversationsRepository
) {
operator fun invoke(peerIds: List<Int>): Flow<State<List<VkConversation>>> = flow {
emit(State.Loading)
val newState = conversationsRepository
.getConversationsById(peerIds = peerIds)
.mapToState()
emit(newState)
}
}
@@ -6,6 +6,7 @@ import dev.meloda.fast.domain.AccountUseCaseImpl
import dev.meloda.fast.domain.GetCurrentAccountUseCase
import dev.meloda.fast.domain.GetLocalUserByIdUseCase
import dev.meloda.fast.domain.GetLocalUsersByIdsUseCase
import dev.meloda.fast.domain.LoadConversationsByIdUseCase
import dev.meloda.fast.domain.LoadUserByIdUseCase
import dev.meloda.fast.domain.LoadUsersByIdsUseCase
import dev.meloda.fast.domain.StoreUsersUseCase
@@ -24,4 +25,6 @@ val domainModule = module {
singleOf(::AccountUseCaseImpl) bind AccountUseCase::class
singleOf(::GetCurrentAccountUseCase)
singleOf(::LoadConversationsByIdUseCase)
}
@@ -1,12 +1,12 @@
package dev.meloda.fast.model.api.responses
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import dev.meloda.fast.model.api.data.VkContactData
import dev.meloda.fast.model.api.data.VkConversationData
import dev.meloda.fast.model.api.data.VkGroupData
import dev.meloda.fast.model.api.data.VkMessageData
import dev.meloda.fast.model.api.data.VkUserData
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class ConversationsGetResponse(
@@ -18,6 +18,15 @@ data class ConversationsGetResponse(
@Json(name = "contacts") val contacts: List<VkContactData>?
)
@JsonClass(generateAdapter = true)
data class ConversationsGetByIdResponse(
@Json(name = "count") val count: Int,
@Json(name = "items") val items: List<VkConversationData>,
@Json(name = "profiles") val profiles: List<VkUserData>?,
@Json(name = "groups") val groups: List<VkGroupData>?,
@Json(name = "contacts") val contacts: List<VkContactData>?
)
@JsonClass(generateAdapter = true)
data class ConversationsResponseItem(
@Json(name = "conversation") val conversation: VkConversationData,
@@ -1,10 +1,11 @@
package dev.meloda.fast.network.service.conversations
import com.slack.eithernet.ApiResult
import dev.meloda.fast.model.api.responses.ConversationsDeleteResponse
import dev.meloda.fast.model.api.responses.ConversationsGetByIdResponse
import dev.meloda.fast.model.api.responses.ConversationsGetResponse
import dev.meloda.fast.network.ApiResponse
import dev.meloda.fast.network.RestApiError
import com.slack.eithernet.ApiResult
import retrofit2.http.FieldMap
import retrofit2.http.FormUrlEncoded
import retrofit2.http.POST
@@ -17,6 +18,12 @@ interface ConversationsService {
@FieldMap params: Map<String, String>
): ApiResult<ApiResponse<ConversationsGetResponse>, RestApiError>
@FormUrlEncoded
@POST(ConversationsUrls.GET_BY_ID)
suspend fun getConversationsById(
@FieldMap params: Map<String, String>
): ApiResult<ApiResponse<ConversationsGetByIdResponse>, RestApiError>
@FormUrlEncoded
@POST(ConversationsUrls.DELETE)
suspend fun delete(
@@ -5,6 +5,7 @@ import dev.meloda.fast.common.AppConstants
object ConversationsUrls {
const val GET = "${AppConstants.URL_API}/messages.getConversations"
const val GET_BY_ID = "${AppConstants.URL_API}/messages.getConversationsById"
const val DELETE = "${AppConstants.URL_API}/messages.deleteConversation"
const val PIN = "${AppConstants.URL_API}/messages.pinConversation"
const val UNPIN = "${AppConstants.URL_API}/messages.unpinConversation"