Skip to content

Commit

Permalink
에러 페이지 대응 (#447)
Browse files Browse the repository at this point in the history
* feat: 시험 결과 화면에 에러 화면 적용

* feat: 친구 목록 화면에 에러 화면 적용

* feat: 시험 문제 풀기 화면에 에러 화면 적용

* feat: 검색 화면에 에러 화면 적용

* feat: 프로필, 타인 화면에 에러 화면 적용

* feat: 알림 화면에 에러 화면 적용

* feat: 명예의 전당 화면에 에러 화면 적용

* feat: 홈 화면에 에러 화면 적용 (점보트론 기준으로만 작업)

* bug: lint 오류 수정
  • Loading branch information
riflockle7 authored Apr 30, 2023
1 parent f7e2245 commit 9d1c2a7
Show file tree
Hide file tree
Showing 27 changed files with 368 additions and 174 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import team.duckie.app.android.feature.ui.exam.result.ExamResultActivity
import team.duckie.app.android.feature.ui.exam.result.R
import team.duckie.app.android.feature.ui.exam.result.viewmodel.ExamResultState
import team.duckie.app.android.feature.ui.exam.result.viewmodel.ExamResultViewModel
import team.duckie.app.android.shared.ui.compose.ErrorScreen
import team.duckie.app.android.shared.ui.compose.quack.QuackCrossfade
import team.duckie.app.android.util.compose.activityViewModel
import team.duckie.quackquack.ui.border.QuackBorder
Expand Down Expand Up @@ -99,13 +101,13 @@ internal fun ExamResultScreen(
}
},
) { padding ->
QuackCrossfade(targetState = state.isReportLoading) {
QuackCrossfade(targetState = state) {
when (it) {
true -> {
is ExamResultState.Loading -> {
LoadingIndicator()
}

false -> {
is ExamResultState.Success -> {
Box(
modifier = Modifier
.fillMaxSize()
Expand All @@ -115,10 +117,18 @@ internal fun ExamResultScreen(
) {
QuackImage(
modifier = Modifier.fillMaxSize(),
src = state.reportUrl,
src = it.reportUrl,
)
}
}

is ExamResultState.Error -> {
ErrorScreen(
Modifier,
false,
onRetryClick = viewModel::initState,
)
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,14 @@

package team.duckie.app.android.feature.ui.exam.result.viewmodel

data class ExamResultState(
val isReportLoading: Boolean = true,
val reportUrl: String = "",
)
sealed class ExamResultState {
object Loading : ExamResultState()

data class Success(
val reportUrl: String = "",
) : ExamResultState()

data class Error(
val exception: Throwable,
) : ExamResultState()
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class ExamResultViewModel @Inject constructor(
) : ViewModel(),
ContainerHost<ExamResultState, ExamResultSideEffect> {
override val container: Container<ExamResultState, ExamResultSideEffect> = container(
ExamResultState(),
ExamResultState.Loading,
)

fun initState() {
Expand All @@ -51,20 +51,20 @@ class ExamResultViewModel @Inject constructor(
submitted: ExamInstanceSubmitBody,
) = intent {
reduce {
state.copy(isReportLoading = true)
ExamResultState.Loading
}
makeExamInstanceSubmitUseCase(
id = examId,
body = submitted,
).onSuccess { submit: ExamInstanceSubmit ->
reduce {
state.copy(
isReportLoading = false,
reportUrl = submit.examScoreImageUrl,
)
ExamResultState.Success(reportUrl = submit.examScoreImageUrl)
}
}.onFailure {
it.printStackTrace()
reduce {
ExamResultState.Error(exception = it)
}
postSideEffect(ExamResultSideEffect.ReportError(it))
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import kotlinx.coroutines.launch
import team.duckie.app.android.feature.ui.friends.viewmodel.FriendsViewModel
import team.duckie.app.android.feature.ui.friends.viewmodel.state.FriendsState
import team.duckie.app.android.shared.ui.compose.BackPressedHeadLine2TopAppBar
import team.duckie.app.android.shared.ui.compose.ErrorScreen
import team.duckie.app.android.shared.ui.compose.NoItemScreen
import team.duckie.app.android.shared.ui.compose.Spacer
import team.duckie.app.android.shared.ui.compose.UserFollowingLayout
Expand Down Expand Up @@ -86,29 +87,37 @@ internal fun FriendScreen(
pageCount = FriendsType.values().size,
state = pagerState,
) { index ->
FriendScreenInternal(
isLoading = state.isLoading,
isMine = state.isMine,
type = FriendsType.fromIndex(index),
state = state,
onClickFollowByFollower = { userId, follow ->
viewModel.followUser(
userId = userId,
isFollowing = follow,
type = FriendsType.Follower,
)
},
onClickFollowByFollowing = { userId, follow ->
viewModel.followUser(
userId = userId,
isFollowing = follow,
type = FriendsType.Following,
)
},
onClickUserProfile = { userId ->
viewModel.navigateToUserProfile(userId)
},
)
if (state.isError) {
ErrorScreen(
Modifier,
false,
onRetryClick = { viewModel.initState() },
)
} else {
FriendScreenInternal(
isLoading = state.isLoading,
isMine = state.isMine,
type = FriendsType.fromIndex(index),
state = state,
onClickFollowByFollower = { userId, follow ->
viewModel.followUser(
userId = userId,
isFollowing = follow,
type = FriendsType.Follower,
)
},
onClickFollowByFollowing = { userId, follow ->
viewModel.followUser(
userId = userId,
isFollowing = follow,
type = FriendsType.Following,
)
},
onClickUserProfile = { userId ->
viewModel.navigateToUserProfile(userId)
},
)
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,72 +41,65 @@ internal class FriendsViewModel @Inject constructor(
override val container = container<FriendsState, FriendsSideEffect>(FriendsState())

init {
val userId = savedStateHandle.getStateFlow(Extras.UserId, 0)
initState(userId.value)
initState()
}

private fun initState(
userId: Int,
) = intent {
updateLoadingState(true)
val result = getMeUseCase()
internal fun initState() = intent {
val userId = savedStateHandle.getStateFlow(Extras.UserId, 0).value
startLoadingState()

getMeUseCase()
.onSuccess { me ->
reduce { state.copy(me = me) }
val myId = me.id
val isMine = userId == myId

reduce { state.copy(me = me, isMine = isMine) }

val targetId = if (isMine) myId else userId
fetchUserFollowers(targetId)
fetchUserFollowings(targetId)
}
.onFailure {
reduce { state.copy(isError = true, isLoading = false) }
postSideEffect(FriendsSideEffect.ReportError(it))
}.also {
updateLoadingState(false)
}

if (result.isSuccess) {
val myId = result.getOrNull()?.id ?: 0
val isMine = userId == myId

reduce { state.copy(isMine = isMine) }

val targetId = if (isMine) myId else userId
fetchUserFollowers(targetId)
fetchUserFollowings(targetId)
}
}

private fun fetchUserFollowers(userId: Int) = intent {
updateLoadingState(true)
fetchUserFollowersUseCase(userId)
.onSuccess { followers ->
reduce {
state.copy(
isLoading = false,
followers = followers.fastMap(User::toUiModel).toImmutableList(),
)
}
}.onFailure {
reduce { state.copy(isError = true, isLoading = false) }
postSideEffect(FriendsSideEffect.ReportError(it))
}.also {
updateLoadingState(false)
}
}

private fun fetchUserFollowings(userId: Int) = intent {
updateLoadingState(true)
fetchUserFollowingsUseCase(userId)
.onSuccess { followers ->
reduce {
state.copy(
isLoading = false,
followings = followers.fastMap(User::toUiModel).toImmutableList(),
)
}
}.onFailure {
reduce { state.copy(isError = true, isLoading = false) }
postSideEffect(FriendsSideEffect.ReportError(it))
}.also {
updateLoadingState(false)
}
}

private fun updateLoadingState(loading: Boolean) = intent {
private fun startLoadingState() = intent {
reduce {
state.copy(
isLoading = loading,
isError = false,
isLoading = true,
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ internal data class FriendsState(
val me: User ? = null,

val isLoading: Boolean = true,
val isError: Boolean = false,
val isMine: Boolean = true,

val followers: ImmutableList<Friend> = skeletonFriends,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import org.orbitmvi.orbit.compose.collectAsState
import team.duckie.app.android.feature.ui.home.constants.HomeStep
import team.duckie.app.android.feature.ui.home.viewmodel.home.HomeSideEffect
import team.duckie.app.android.feature.ui.home.viewmodel.home.HomeViewModel
import team.duckie.app.android.shared.ui.compose.ErrorScreen
import team.duckie.app.android.shared.ui.compose.dialog.ReportBottomSheetDialog
import team.duckie.app.android.shared.ui.compose.quack.QuackCrossfade
import team.duckie.app.android.util.exception.handling.reporter.reportToCrashlyticsIfNeeded
Expand Down Expand Up @@ -79,8 +80,13 @@ internal fun HomeScreen(
QuackCrossfade(
targetState = state.homeSelectedIndex,
) { page ->
when (page) {
HomeStep.HomeRecommendScreen -> HomeRecommendScreen(
when {
state.isError -> ErrorScreen(
modifier = Modifier.fillMaxSize(),
onRetryClick = vm::fetchJumbotrons,
)

page == HomeStep.HomeRecommendScreen -> HomeRecommendScreen(
state = state,
homeViewModel = vm,
navigateToCreateProblem = navigateToCreateProblem,
Expand All @@ -94,7 +100,7 @@ internal fun HomeScreen(
},
)

HomeStep.HomeFollowingScreen -> if (state.isFollowingExist) {
page == HomeStep.HomeFollowingScreen -> if (state.isFollowingExist) {
HomeRecommendFollowingExamScreen(
modifier = Modifier.padding(HomeHorizontalPadding),
state = state,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,20 @@

package team.duckie.app.android.feature.ui.home.screen.mypage

import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import team.duckie.app.android.feature.ui.home.R
import team.duckie.app.android.feature.ui.home.viewmodel.mypage.MyPageViewModel
import team.duckie.app.android.feature.ui.home.viewmodel.mypage.MyPageSideEffect
import team.duckie.app.android.feature.ui.profile.screen.MyProfileScreen
import team.duckie.app.android.shared.ui.compose.ErrorScreen
import team.duckie.app.android.shared.ui.compose.LoadingScreen
import team.duckie.app.android.shared.ui.compose.dialog.ReportAlreadyExists
import team.duckie.app.android.util.compose.LaunchOnLifecycle
import team.duckie.app.android.util.compose.ToastWrapper
Expand Down Expand Up @@ -86,17 +91,28 @@ internal fun MyPageScreen(
}

with(state) {
MyProfileScreen(
userProfile = userProfile,
isLoading = isLoading,
onClickSetting = viewModel::clickSetting,
onClickNotification = viewModel::clickNotification,
onClickEditProfile = viewModel::clickEditProfile,
onClickEditTag = { viewModel.clickEditTag(context.getString(R.string.provide_after)) },
onClickExam = viewModel::clickExam,
onClickMakeExam = viewModel::clickMakeExam,
onClickTag = viewModel::onClickTag,
onClickFriend = navigateToFriend,
)
if (isLoading) {
LoadingScreen(initState = {})
} else if (isError) {
ErrorScreen(
modifier = Modifier
.fillMaxSize()
.statusBarsPadding(),
onRetryClick = viewModel::getUserProfile,
)
} else {
MyProfileScreen(
userProfile = userProfile,
isLoading = false,
onClickSetting = viewModel::clickSetting,
onClickNotification = viewModel::clickNotification,
onClickEditProfile = viewModel::clickEditProfile,
onClickEditTag = { viewModel.clickEditTag(context.getString(R.string.provide_after)) },
onClickExam = viewModel::clickExam,
onClickMakeExam = viewModel::clickMakeExam,
onClickTag = viewModel::onClickTag,
onClickFriend = navigateToFriend,
)
}
}
}
Loading

0 comments on commit 9d1c2a7

Please sign in to comment.