Skip to content

Commit

Permalink
✨ 네트워크 로딩 프로그래스 화면 및 네트워크 에러 다이얼로그 화면 생성
Browse files Browse the repository at this point in the history
  • Loading branch information
yonghanJu committed Oct 7, 2024
1 parent 7c26784 commit 3ebc46f
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 7 deletions.
29 changes: 27 additions & 2 deletions app/src/main/java/com/whyranoid/walkie/KoinModules.kt
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ import com.whyranoid.presentation.screens.mypage.editprofile.EditProfileViewMode
import com.whyranoid.presentation.screens.mypage.following.FollowingViewModel
import com.whyranoid.presentation.screens.setting.SettingViewModel
import com.whyranoid.presentation.viewmodel.AddPostViewModel
import com.whyranoid.presentation.util.ApiResponseDialog
import com.whyranoid.presentation.viewmodel.CommunityScreenViewModel
import com.whyranoid.presentation.viewmodel.RunningEditViewModel
import com.whyranoid.presentation.viewmodel.RunningViewModel
Expand All @@ -104,6 +105,7 @@ import com.whyranoid.presentation.viewmodel.challenge.ChallengeDetailViewModel
import com.whyranoid.presentation.viewmodel.challenge.ChallengeExitViewModel
import com.whyranoid.presentation.viewmodel.challenge.ChallengeMainViewModel
import com.whyranoid.walkie.walkiedialog.DialogViewModel
import com.whyranoid.walkie.walkiedialog.NetworkInterceptor
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Response
Expand All @@ -120,7 +122,19 @@ val viewModelModule =
viewModel { ChallengeMainViewModel(get(), get(), get(), get(), get()) }
viewModel { ChallengeDetailViewModel(get(), get()) }
viewModel { ChallengeExitViewModel(get(), get()) }
viewModel { UserPageViewModel(get(), get(), get(), get(), get(), get(), get(), get(), get()) }
viewModel {
UserPageViewModel(
get(),
get(),
get(),
get(),
get(),
get(),
get(),
get(),
get()
)
}
viewModel { RunningViewModel(get(), get(), get(), get(), get(), get()) }
viewModel { RunningEditViewModel() }
viewModel { SplashViewModel(get()) }
Expand Down Expand Up @@ -200,7 +214,7 @@ val useCaseModule =
single { GetMyFollowingUseCase(get(), get()) }
single { SendCommentUseCase(get(), get()) }
single { GetUserUseCase(get()) }
single { ChangeChallengeStatusUseCase(get(), get())}
single { ChangeChallengeStatusUseCase(get(), get()) }
single { GetUserPostsUseCase(get(), get()) }
}

Expand Down Expand Up @@ -242,6 +256,17 @@ val networkModule =
HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
},
).addInterceptor(
NetworkInterceptor(
onRequest = { ApiResponseDialog.startLoading() },
onResponse = { ApiResponseDialog.finishLoad(it) },
excludedUrls = listOf(
Regex("/api/follow/(\\d+)/following"), // polling 방식 업데이트
Regex("/api/follow/(\\d+)/walking-followings"), // polling 방식 업데이트
Regex("/api/community/listup-post"), // 커뮤니티 탭, 자체 로딩바 있음
Regex("/api/community/upload-post") // 게시글 업로드, 자체 로딩바 있음
)
)
)
.build()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.whyranoid.walkie.walkiedialog

import android.util.Log
import okhttp3.Interceptor
import okhttp3.Response

class NetworkInterceptor(
private val onRequest: () -> Unit,
private val onResponse: (isSuccessFul: Boolean) -> Unit,
private val excludedUrls: List<Regex>,
) : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
Log.d("ju0828", request.url.toString())

Log.d("ju0828", "${request.url} validate = ${excludedUrls.all { request.url.toString().contains(it).not() }}")

// 요청 URL이 제외할 URL과 같지 않으면 콜백 호출
if (excludedUrls.all { request.url.toString().contains(it).not() }) {
onRequest() // 요청 전 콜백 호출
Log.d("ju0828", "${request.url} request called")

}

return try {
val response = chain.proceed(request)

// 응답 후 콜백 호출
if (excludedUrls.all { request.url.toString().contains(it).not() }) {
onResponse(response.isSuccessful) // 응답 후 콜백 호출
}
response
} catch (e: Exception) {
// 예외가 발생한 경우 (타임아웃 포함)
if (e is java.net.SocketTimeoutException) {
onResponse(false)
}
throw e // 예외를 다시 던져서 호출자에게 알림
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.whyranoid.presentation.reusable

import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
Expand All @@ -17,6 +18,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.whyranoid.presentation.theme.WalkieColor
Expand All @@ -28,16 +30,31 @@ fun CircleProgressWithText(
modifier: Modifier = Modifier,
text: String,
) {
Box(modifier = modifier.fillMaxSize().alpha(0.5f).background(WalkieColor.GrayDefault))
Box(
modifier = modifier
.fillMaxSize()
.alpha(0.5f)
.background(WalkieColor.GrayDefault)
.pointerInput(Unit) { // 터치 이벤트 소비
detectTapGestures(onPress = {
// 아무것도 하지 않음, 터치 이벤트 소비
})
})
Box(modifier = Modifier.fillMaxSize()) {
Column(
modifier = modifier.width(200.dp).height(160.dp).align(Alignment.Center)
.clip(RoundedCornerShape(20.dp)).background(Color.White),
modifier = modifier
.width(200.dp)
.height(160.dp)
.align(Alignment.Center)
.clip(RoundedCornerShape(20.dp))
.background(Color.White),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
) {
Text(text, style = WalkieTypography.SubTitle)
Spacer(modifier = Modifier.height(20.dp))
if (text.isNotEmpty()) {
Text(text, style = WalkieTypography.SubTitle)
Spacer(modifier = Modifier.height(20.dp))
}
CircularProgressIndicator()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeDrawingPadding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.BottomNavigation
import androidx.compose.material.BottomNavigationItem
import androidx.compose.material.Icon
Expand All @@ -13,6 +14,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
Expand All @@ -27,6 +29,7 @@ import androidx.navigation.compose.composable
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import com.whyranoid.domain.model.post.Post
import com.whyranoid.presentation.reusable.CircleProgressWithText
import com.whyranoid.presentation.screens.Screen.Companion.bottomNavigationItems
import com.whyranoid.presentation.screens.challenge.ChallengeCompleteScreen
import com.whyranoid.presentation.screens.challenge.ChallengeDetailScreen
Expand All @@ -47,6 +50,8 @@ import com.whyranoid.presentation.screens.signin.SignInScreen
import com.whyranoid.presentation.screens.splash.SplashScreen
import com.whyranoid.presentation.theme.WalkieColor
import com.whyranoid.presentation.theme.WalkieTypography
import com.whyranoid.presentation.util.CustomDialog
import com.whyranoid.presentation.util.ApiResponseDialog
import com.whyranoid.presentation.viewmodel.SplashState
import com.whyranoid.presentation.viewmodel.SplashViewModel
import org.koin.androidx.compose.koinViewModel
Expand Down Expand Up @@ -249,5 +254,18 @@ fun AppScreenContent(
)
}
}

val isLoading = ApiResponseDialog.isLoading.collectAsStateWithLifecycle()
val isError = ApiResponseDialog.isShowError.collectAsStateWithLifecycle()
if (isLoading.value) {
CircleProgressWithText(text = "")
} else if (isError.value) {
CustomDialog(
title = "네트워크 연결 실패",
description = "네트워크 연결이 끊겼거나 속도가 느립니다.\n다시 시도해주세요.",
onAction = { ApiResponseDialog.closeErrorDialog() },
Modifier.clip(RoundedCornerShape(20.dp))
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.whyranoid.presentation.util


import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import java.util.concurrent.atomic.AtomicInteger

object ApiResponseDialog {
private val loadingCount = AtomicInteger(0)

private val _isLaoding = MutableStateFlow(false)
val isLoading get() = _isLaoding.asStateFlow()

private val _isShowError = MutableStateFlow(false)

val isShowError get() = _isShowError.asStateFlow()

fun startLoading() {
if (loadingCount.incrementAndGet() > 0) _isLaoding.value = true
}

fun finishLoad(isSuccessFul: Boolean) {
if (loadingCount.decrementAndGet() == 0) _isLaoding.value = false
if (isSuccessFul.not()) {
_isLaoding.value = false
_isShowError.value = true
}
}

fun closeErrorDialog() {
_isShowError.value = false
}
}

0 comments on commit 3ebc46f

Please sign in to comment.