support for articles; ui & ux & logic fixes for 2fa and captcha screens; fix mentions;
This commit is contained in:
@@ -40,12 +40,15 @@ class OAuthRepositoryImpl(
|
||||
requireNotNull(result.error)
|
||||
}
|
||||
|
||||
else -> throw IllegalStateException("Unknown result")
|
||||
is ApiResult.Failure.ApiFailure -> TODO()
|
||||
|
||||
// is ApiResult.Failure.ApiFailure -> TODO()
|
||||
// is ApiResult.Failure.HttpFailure -> TODO()
|
||||
// is ApiResult.Failure.NetworkFailure -> TODO()
|
||||
// is ApiResult.Failure.UnknownFailure -> TODO()
|
||||
is ApiResult.Failure.NetworkFailure -> {
|
||||
// TODO: 13/07/2024, Danil Nikolaev: implement showing network error
|
||||
TODO()
|
||||
}
|
||||
is ApiResult.Failure.UnknownFailure -> TODO()
|
||||
|
||||
else -> throw IllegalStateException("Unknown result")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,6 +104,7 @@
|
||||
<string name="message_attachments_audio_playlist">Playlist</string>
|
||||
<string name="message_attachments_podcast">Podcast</string>
|
||||
<string name="message_attachments_narrative">Narrative</string>
|
||||
<string name="message_attachments_article">Article</string>
|
||||
|
||||
<string name="chat_interaction_uploading_file">Uploading file</string>
|
||||
<string name="chat_interaction_uploading_photo">Uploading photo</string>
|
||||
|
||||
@@ -32,6 +32,9 @@ dependencies {
|
||||
implementation(libs.moshi.kotlin)
|
||||
ksp(libs.moshi.kotlin.codegen)
|
||||
|
||||
implementation(platform(libs.compose.bom))
|
||||
implementation(libs.bundles.compose)
|
||||
|
||||
implementation(libs.room.ktx)
|
||||
implementation(libs.room.runtime)
|
||||
ksp(libs.room.compiler)
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
package com.meloda.app.fast.model
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
|
||||
@Immutable
|
||||
sealed class BaseError {
|
||||
|
||||
data object SessionExpired : BaseError()
|
||||
}
|
||||
|
||||
@@ -26,7 +26,8 @@ enum class AttachmentType(var value: String) {
|
||||
ARTIST("artist"),
|
||||
AUDIO_PLAYLIST("audio_playlist"),
|
||||
PODCAST("podcast"),
|
||||
NARRATIVE("narrative");
|
||||
NARRATIVE("narrative"),
|
||||
ARTICLE("article");
|
||||
|
||||
fun isMultiple(): Boolean = this in listOf(PHOTO, VIDEO, AUDIO, FILE)
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.meloda.app.fast.model.api.data
|
||||
|
||||
import com.meloda.app.fast.model.api.domain.VkArticleDomain
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class VkArticleData(
|
||||
@Json(name = "id") val id: Int
|
||||
) : VkAttachmentData {
|
||||
|
||||
fun toDomain(): VkArticleDomain = VkArticleDomain(
|
||||
id = id
|
||||
)
|
||||
}
|
||||
+3
-1
@@ -31,7 +31,8 @@ data class VkAttachmentItemData(
|
||||
@Json(name = "audios") val audios: List<VkAudioData>?,
|
||||
@Json(name = "audio_playlist") val audioPlaylist: VkAudioPlaylistData?,
|
||||
@Json(name = "podcast") val podcast: VkPodcastData?,
|
||||
@Json(name = "narrative") val narrative: VkNarrativeData?
|
||||
@Json(name = "narrative") val narrative: VkNarrativeData?,
|
||||
@Json(name = "article") val article: VkArticleData?
|
||||
) {
|
||||
fun toDomain(): VkAttachment = when (AttachmentType.parse(type)) {
|
||||
AttachmentType.UNKNOWN -> VkUnknownAttachment
|
||||
@@ -58,5 +59,6 @@ data class VkAttachmentItemData(
|
||||
AttachmentType.AUDIO_PLAYLIST -> audioPlaylist?.toDomain()
|
||||
AttachmentType.PODCAST -> podcast?.toDomain()
|
||||
AttachmentType.NARRATIVE -> narrative?.toDomain()
|
||||
AttachmentType.ARTICLE -> article?.toDomain()
|
||||
} ?: VkUnknownAttachment
|
||||
}
|
||||
|
||||
@@ -10,11 +10,11 @@ data class VkGroupData(
|
||||
@Json(name = "id") val id: Int,
|
||||
@Json(name = "name") val name: String,
|
||||
@Json(name = "screen_name") val screenName: String,
|
||||
@Json(name = "is_closed") val isClosed: Int,
|
||||
@Json(name = "is_closed") val isClosed: Int?,
|
||||
@Json(name = "type") val type: String,
|
||||
@Json(name = "is_admin") val isAdmin: Int,
|
||||
@Json(name = "is_member") val isMember: Int,
|
||||
@Json(name = "is_advertiser") val isAdvertiser: Int,
|
||||
@Json(name = "is_admin") val isAdmin: Int?,
|
||||
@Json(name = "is_member") val isMember: Int?,
|
||||
@Json(name = "is_advertiser") val isAdvertiser: Int?,
|
||||
@Json(name = "photo_50") val photo50: String?,
|
||||
@Json(name = "photo_100") val photo100: String?,
|
||||
@Json(name = "photo_200") val photo200: String?,
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.meloda.app.fast.model.api.domain
|
||||
|
||||
import com.meloda.app.fast.model.api.data.AttachmentType
|
||||
|
||||
data class VkArticleDomain(
|
||||
val id: Int
|
||||
) : VkAttachment {
|
||||
|
||||
override val type: AttachmentType = AttachmentType.ARTICLE
|
||||
}
|
||||
@@ -75,7 +75,7 @@ data class InvalidCredentialsError(
|
||||
)
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class WrongTwoFaCode(
|
||||
data class WrongTwoFaCodeError(
|
||||
@Json(name = "error") override val error: String, // "invalid_request"
|
||||
@Json(name = "error_description") override val errorDescription: String,
|
||||
@Json(name = "error_type") override val errorType: String // "wrong_otp"
|
||||
@@ -86,7 +86,7 @@ data class WrongTwoFaCode(
|
||||
)
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class WrongTwoFaCodeFormat(
|
||||
data class WrongTwoFaCodeFormatError(
|
||||
@Json(name = "error") override val error: String, // "invalid_request"
|
||||
@Json(name = "error_description") override val errorDescription: String,
|
||||
@Json(name = "error_type") override val errorType: String // "otp_format_is_incorrect"
|
||||
@@ -96,6 +96,17 @@ data class WrongTwoFaCodeFormat(
|
||||
errorType = errorType
|
||||
)
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class TooManyTriesError(
|
||||
@Json(name = "error") override val error: String, // "9;Flood control"
|
||||
@Json(name = "error_description") override val errorDescription: String,
|
||||
@Json(name = "error_type") override val errorType: String // "password_bruteforce_attempt"
|
||||
) : OAuthError(
|
||||
error = error,
|
||||
errorDescription = errorDescription,
|
||||
errorType = errorType
|
||||
)
|
||||
|
||||
fun OAuthError.toDomain(): OAuthErrorDomain? = when (this) {
|
||||
is ValidationRequiredError -> {
|
||||
OAuthErrorDomain.ValidationRequiredError(
|
||||
@@ -129,13 +140,17 @@ fun OAuthError.toDomain(): OAuthErrorDomain? = when (this) {
|
||||
OAuthErrorDomain.InvalidCredentialsError
|
||||
}
|
||||
|
||||
is WrongTwoFaCode -> {
|
||||
is WrongTwoFaCodeError -> {
|
||||
OAuthErrorDomain.WrongTwoFaCode
|
||||
}
|
||||
|
||||
is WrongTwoFaCodeFormat -> {
|
||||
is WrongTwoFaCodeFormatError -> {
|
||||
OAuthErrorDomain.WrongTwoFaCodeFormat
|
||||
}
|
||||
|
||||
is TooManyTriesError -> {
|
||||
OAuthErrorDomain.TooManyTriesError
|
||||
}
|
||||
|
||||
else -> null
|
||||
}
|
||||
|
||||
@@ -27,5 +27,7 @@ sealed class OAuthErrorDomain {
|
||||
data object InvalidCredentialsError : OAuthErrorDomain()
|
||||
data object WrongTwoFaCode : OAuthErrorDomain()
|
||||
data object WrongTwoFaCodeFormat : OAuthErrorDomain()
|
||||
data object TooManyTriesError: OAuthErrorDomain()
|
||||
|
||||
data object UnknownError : OAuthErrorDomain()
|
||||
}
|
||||
|
||||
@@ -110,6 +110,11 @@ internal class ResultCall<R : Any, E : OAuthError>(
|
||||
.fromJson(errorBodyString.orEmpty()) ?: return
|
||||
|
||||
val error: OAuthError? = when (baseError.error) {
|
||||
"9;Flood control" -> {
|
||||
moshi.adapter(TooManyTriesError::class.java)
|
||||
.fromJson(errorBodyString.orEmpty())
|
||||
}
|
||||
|
||||
"invalid_client" -> {
|
||||
moshi.adapter(InvalidCredentialsError::class.java)
|
||||
.fromJson(errorBodyString.orEmpty())
|
||||
@@ -123,12 +128,12 @@ internal class ResultCall<R : Any, E : OAuthError>(
|
||||
"invalid_request" -> {
|
||||
when (val type = baseError.errorType) {
|
||||
"wrong_otp" -> {
|
||||
moshi.adapter(WrongTwoFaCode::class.java)
|
||||
moshi.adapter(WrongTwoFaCodeError::class.java)
|
||||
.fromJson(errorBodyString.orEmpty())
|
||||
}
|
||||
|
||||
"otp_format_is_incorrect" -> {
|
||||
moshi.adapter(WrongTwoFaCodeFormat::class.java)
|
||||
moshi.adapter(WrongTwoFaCodeFormatError::class.java)
|
||||
.fromJson(errorBodyString.orEmpty())
|
||||
}
|
||||
|
||||
|
||||
@@ -51,10 +51,12 @@ object VkOAuthErrors {
|
||||
const val NEED_CAPTCHA = "need_captcha"
|
||||
const val INVALID_CLIENT = "invalid_client"
|
||||
const val INVALID_REQUEST = "invalid_request"
|
||||
const val FLOOD_CONTROL = "9;Flood control"
|
||||
|
||||
}
|
||||
|
||||
object VkErrorTypes {
|
||||
const val WRONG_OTP_FORMAT = "otp_format_is_incorrect"
|
||||
const val WRONG_OTP = "wrong_otp"
|
||||
const val PASSWORD_BRUTEFORCE_ATTEMPT = "password_bruteforce_attempt"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user