feat: 贴页面错误提示

This commit is contained in:
HuanCheng65 2023-07-17 13:31:17 +08:00
parent 2f1ab3b038
commit 67052d4a91
No known key found for this signature in database
GPG Key ID: 5EC9DD60A32C7360
9 changed files with 3778 additions and 3647 deletions

View File

@ -4,4 +4,8 @@ import com.huanchengfly.tieba.post.api.Error.ERROR_NETWORK
class NoConnectivityException(
msg: String = "No internet!"
) : TiebaLocalException(ERROR_NETWORK, msg)
) : TiebaLocalException(ERROR_NETWORK, msg) {
override fun toString(): String {
return "NoConnectivityException(message=$message)"
}
}

View File

@ -4,7 +4,11 @@ import com.huanchengfly.tieba.post.api.models.CommonResponse
class TiebaApiException(
private val commonResponse: CommonResponse
) : TiebaException(commonResponse.errorMsg?.takeIf { it.isNotEmpty() } ?: "未知错误") {
) : TiebaException(commonResponse.errorMsg.takeIf { it.isNotEmpty() } ?: "未知错误") {
override val code: Int
get() = commonResponse.errorCode ?: -1
get() = commonResponse.errorCode
override fun toString(): String {
return "TiebaApiException(code=$code, message=$message, commonResponse=$commonResponse)"
}
}

View File

@ -4,4 +4,13 @@ import java.io.IOException
abstract class TiebaException(message: String) : IOException(message) {
abstract val code: Int
override fun toString(): String {
return "TiebaException(code=$code, message=$message)"
}
}
object TiebaUnknownException : TiebaException("未知错误") {
override val code: Int
get() = -1
}

View File

@ -3,4 +3,8 @@ package com.huanchengfly.tieba.post.api.retrofit.exception
open class TiebaLocalException(
override val code: Int,
msg: String
) : TiebaException(msg)
) : TiebaException(msg) {
override fun toString(): String {
return "TiebaLocalException(code=$code, message=$message)"
}
}

View File

@ -4,4 +4,8 @@ import com.huanchengfly.tieba.post.api.Error.ERROR_NOT_LOGGED_IN
class TiebaNotLoggedInException(
msg: String = "Not logged in!"
) : TiebaLocalException(ERROR_NOT_LOGGED_IN, msg)
) : TiebaLocalException(ERROR_NOT_LOGGED_IN, msg) {
override fun toString(): String {
return "TiebaNotLoggedInException(message=$message)"
}
}

View File

@ -120,6 +120,7 @@ import com.huanchengfly.tieba.post.ui.widgets.compose.BackNavigationIcon
import com.huanchengfly.tieba.post.ui.widgets.compose.Button
import com.huanchengfly.tieba.post.ui.widgets.compose.Card
import com.huanchengfly.tieba.post.ui.widgets.compose.ConfirmDialog
import com.huanchengfly.tieba.post.ui.widgets.compose.ErrorScreen
import com.huanchengfly.tieba.post.ui.widgets.compose.HorizontalDivider
import com.huanchengfly.tieba.post.ui.widgets.compose.LazyLoad
import com.huanchengfly.tieba.post.ui.widgets.compose.ListMenuItem
@ -457,6 +458,14 @@ fun ThreadPage(
prop1 = ThreadUiState::isLoadingMore,
initial = false
)
val isError by viewModel.uiState.collectPartialAsState(
prop1 = ThreadUiState::isError,
initial = false
)
val error by viewModel.uiState.collectPartialAsState(
prop1 = ThreadUiState::error,
initial = null
)
val hasMore by viewModel.uiState.collectPartialAsState(
prop1 = ThreadUiState::hasMore,
initial = true
@ -469,10 +478,6 @@ fun ThreadPage(
prop1 = ThreadUiState::hasPrevious,
initial = true
)
val currentPageMin by viewModel.uiState.collectPartialAsState(
prop1 = ThreadUiState::currentPageMin,
initial = 0
)
val currentPageMax by viewModel.uiState.collectPartialAsState(
prop1 = ThreadUiState::currentPageMax,
initial = 0
@ -707,8 +712,14 @@ fun ThreadPage(
ProvideNavigator(navigator = navigator) {
StateScreen(
isEmpty = isEmpty,
isError = false,
isError = isError,
isLoading = isRefreshing,
errorScreen = {
error?.let {
val (e) = it
ErrorScreen(error = e)
}
},
onReload = {
viewModel.send(
ThreadUiIntent.Load(

View File

@ -11,6 +11,7 @@ import com.huanchengfly.tieba.post.api.models.protos.SimpleForum
import com.huanchengfly.tieba.post.api.models.protos.ThreadInfo
import com.huanchengfly.tieba.post.api.models.protos.User
import com.huanchengfly.tieba.post.api.renders
import com.huanchengfly.tieba.post.api.retrofit.exception.TiebaUnknownException
import com.huanchengfly.tieba.post.api.retrofit.exception.getErrorCode
import com.huanchengfly.tieba.post.api.retrofit.exception.getErrorMessage
import com.huanchengfly.tieba.post.api.updateAgreeStatus
@ -108,7 +109,7 @@ class ThreadViewModel @Inject constructor() :
fun ThreadUiIntent.Init.producePartialChange(): Flow<ThreadPartialChange.Init> =
flowOf<ThreadPartialChange.Init>(
ThreadPartialChange.Init.Success(
threadInfo?.title ?: "",
threadInfo?.title.orEmpty(),
threadInfo?.author,
threadInfo,
threadInfo?.firstPostContent?.renders ?: emptyList(),
@ -116,18 +117,14 @@ class ThreadViewModel @Inject constructor() :
seeLz,
sortType,
)
).catch {
emit(
ThreadPartialChange.Init.Failure(
it.getErrorCode(),
it.getErrorMessage()
)
)
}
).catch { emit(ThreadPartialChange.Init.Failure(it)) }
fun ThreadUiIntent.Load.producePartialChange(): Flow<ThreadPartialChange.Load> =
PbPageRepository
.pbPage(threadId, page, postId, forumId, seeLz, sortType, from = from)
.pbPage(
threadId, page, postId, forumId, seeLz, sortType,
from = from.takeIf { it == ThreadPageFrom.FROM_STORE }.orEmpty()
)
.map { response ->
if (
response.data_?.page != null
@ -170,17 +167,10 @@ class ThreadViewModel @Inject constructor() :
seeLz,
sortType,
)
} else ThreadPartialChange.Load.Failure(-1, "未知错误")
} else ThreadPartialChange.Load.Failure(TiebaUnknownException)
}
.onStart { emit(ThreadPartialChange.Load.Start) }
.catch {
emit(
ThreadPartialChange.Load.Failure(
it.getErrorCode(),
it.getErrorMessage()
)
)
}
.catch { emit(ThreadPartialChange.Load.Failure(it)) }
fun ThreadUiIntent.LoadFirstPage.producePartialChange(): Flow<ThreadPartialChange.LoadFirstPage> =
PbPageRepository
@ -220,17 +210,10 @@ class ThreadViewModel @Inject constructor() :
seeLz,
sortType,
)
} else ThreadPartialChange.LoadFirstPage.Failure(-1, "未知错误")
} else ThreadPartialChange.LoadFirstPage.Failure(TiebaUnknownException)
}
.onStart { emit(ThreadPartialChange.LoadFirstPage.Start) }
.catch {
emit(
ThreadPartialChange.LoadFirstPage.Failure(
it.getErrorCode(),
it.getErrorMessage()
)
)
}
.catch { emit(ThreadPartialChange.LoadFirstPage.Failure(it)) }
fun ThreadUiIntent.LoadMore.producePartialChange(): Flow<ThreadPartialChange.LoadMore> =
PbPageRepository
@ -488,6 +471,8 @@ sealed interface ThreadPartialChange : PartialChange<ThreadUiState> {
override fun reduce(oldState: ThreadUiState): ThreadUiState = when (this) {
is Success -> oldState.copy(
isRefreshing = true,
isError = false,
error = null,
title = title,
author = if (author != null) wrapImmutable(author) else null,
threadInfo = threadInfo?.wrapImmutable(),
@ -506,7 +491,10 @@ sealed interface ThreadPartialChange : PartialChange<ThreadUiState> {
sortType = sortType,
)
is Failure -> oldState
is Failure -> oldState.copy(
isError = true,
error = error.wrapImmutable()
)
}
data class Success(
@ -520,8 +508,7 @@ sealed interface ThreadPartialChange : PartialChange<ThreadUiState> {
) : Init()
data class Failure(
val errorCode: Int,
val errorMessage: String
val error: Throwable
) : Init()
}
@ -531,6 +518,8 @@ sealed interface ThreadPartialChange : PartialChange<ThreadUiState> {
is Success -> oldState.copy(
isRefreshing = false,
isError = false,
error = null,
title = title,
author = wrapImmutable(author),
user = wrapImmutable(user),
@ -553,7 +542,11 @@ sealed interface ThreadPartialChange : PartialChange<ThreadUiState> {
sortType = sortType,
)
is Failure -> oldState.copy(isRefreshing = false)
is Failure -> oldState.copy(
isRefreshing = false,
isError = true,
error = error.wrapImmutable()
)
}
object Start : Load()
@ -580,8 +573,7 @@ sealed interface ThreadPartialChange : PartialChange<ThreadUiState> {
) : Load()
data class Failure(
val errorCode: Int,
val errorMessage: String
val error: Throwable,
) : Load()
}
@ -590,6 +582,8 @@ sealed interface ThreadPartialChange : PartialChange<ThreadUiState> {
is Start -> oldState.copy(isRefreshing = true)
is Success -> oldState.copy(
isRefreshing = false,
isError = false,
error = null,
title = title,
author = wrapImmutable(author),
data = data.toImmutableList(),
@ -607,7 +601,11 @@ sealed interface ThreadPartialChange : PartialChange<ThreadUiState> {
sortType = sortType,
)
is Failure -> oldState.copy(isRefreshing = false)
is Failure -> oldState.copy(
isRefreshing = false,
isError = true,
error = error.wrapImmutable(),
)
}
object Start : LoadFirstPage()
@ -630,8 +628,7 @@ sealed interface ThreadPartialChange : PartialChange<ThreadUiState> {
) : LoadFirstPage()
data class Failure(
val errorCode: Int,
val errorMessage: String
val error: Throwable
) : LoadFirstPage()
}
@ -866,6 +863,8 @@ sealed interface ThreadPartialChange : PartialChange<ThreadUiState> {
data class ThreadUiState(
val isRefreshing: Boolean = false,
val isLoadingMore: Boolean = false,
val isError: Boolean = false,
val error: ImmutableHolder<Throwable>? = null,
val hasMore: Boolean = true,
val nextPagePostId: Long = 0,

File diff suppressed because it is too large Load Diff

View File

@ -653,7 +653,7 @@
<string name="no_internet_connectivity">无互联网连接</string>
<string name="connectivity_timeout">连接超时</string>
<string name="title_no_internet_connectivity">网络找不到了</string>
<string name="title_api_error">服务器有一些自己的想法</string>
<string name="title_api_error">啊哦,出错了</string>
<string name="title_unknown_error">发生了一个奇怪的错误…</string>
<string name="message_no_internet_connectivity">%s。请检查你的网络连接是否正常</string>
<string name="message_unknown_error">哦我的老伙计,我向你保证这真的是一个奇怪的错误……</string>