feat: 贴页面错误提示
This commit is contained in:
parent
2f1ab3b038
commit
67052d4a91
|
|
@ -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)"
|
||||
}
|
||||
}
|
||||
|
|
@ -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)"
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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)"
|
||||
}
|
||||
}
|
||||
|
|
@ -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)"
|
||||
}
|
||||
}
|
||||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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>
|
||||
|
|
|
|||
Loading…
Reference in New Issue