Skip to content

Commit

Permalink
Merge pull request #103 from Team-Motivoo/feat/#93-network-checking
Browse files Browse the repository at this point in the history
[feat] 네트워크 연결 상태 확인 (로딩,에러 뷰)
  • Loading branch information
l2zh authored Mar 2, 2024
2 parents b82ab91 + d062e7b commit 740cba2
Show file tree
Hide file tree
Showing 37 changed files with 533 additions and 148 deletions.
1 change: 1 addition & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package sopt.motivoo.data.datasource.remote
package sopt.motivoo.data.datasource.remote.intercepter

import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package sopt.motivoo.data.datasource.remote.intercepter

import okhttp3.Interceptor
import okhttp3.Response
import sopt.motivoo.data.datasource.remote.listener.NetworkErrorListener
import javax.inject.Inject

class ErrorInterceptor @Inject constructor(
private val networkErrorListener: NetworkErrorListener,
) : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
var response = chain.proceed(chain.request())

when (response.code) {

in SERVER_ERROR_START..SERVER_ERROR_END -> {
networkErrorListener.onApiCallFailed()

response.close()
response = chain.proceed(request)
}
}
return response
}

companion object {
private const val SERVER_ERROR_START = 500
private const val SERVER_ERROR_END = 599
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@ package sopt.motivoo.data.datasource.remote.listener

interface AuthTokenRefreshListener {
fun onTokenRefreshFailed()
fun setOnTokenRefreshFailedCallback(callback: () -> Unit)
fun clearOnTokenRefreshFailedCallback()
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,17 @@ package sopt.motivoo.data.datasource.remote.listener
import javax.inject.Inject

class AuthTokenRefreshListenerImpl @Inject constructor() : AuthTokenRefreshListener {
lateinit var onTokenRefreshFailedCallback: (() -> Unit)
private var onTokenRefreshFailedCallback: (() -> Unit)? = null

override fun onTokenRefreshFailed() {
if (this::onTokenRefreshFailedCallback.isInitialized) {
onTokenRefreshFailedCallback()
}
onTokenRefreshFailedCallback?.invoke()
}

override fun setOnTokenRefreshFailedCallback(callback: () -> Unit) {
onTokenRefreshFailedCallback = callback
}

override fun clearOnTokenRefreshFailedCallback() {
onTokenRefreshFailedCallback = null
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package sopt.motivoo.data.datasource.remote.listener

interface NetworkErrorListener {
fun onApiCallFailed()
fun setOnApiCallFailedCallback(callback: () -> Unit)
fun clearOnApiCallFailedCallback()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package sopt.motivoo.data.datasource.remote.listener

import javax.inject.Inject

class NetworkErrorListenerImpl @Inject constructor() : NetworkErrorListener {
private var onApiCallFailedCallback: (() -> Unit)? = null

override fun onApiCallFailed() {
onApiCallFailedCallback?.invoke()
}

override fun setOnApiCallFailedCallback(callback: () -> Unit) {
onApiCallFailedCallback = callback
}

override fun clearOnApiCallFailedCallback() {
onApiCallFailedCallback = null
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package sopt.motivoo.data.repository

import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import sopt.motivoo.domain.repository.NetworkRepository
import sopt.motivoo.util.NetworkState
import javax.inject.Inject

class NetworkRepositoryImpl @Inject constructor(
networkState: NetworkState
) : NetworkRepository {

override val networkStateFlow = networkState.networkState

private val _isLoading = MutableSharedFlow<Boolean>(replay = 1)
override val isLoading get() = _isLoading.asSharedFlow()

override suspend fun setLoading(isLoading: Boolean) {
_isLoading.emit(isLoading)
}
}
15 changes: 15 additions & 0 deletions app/src/main/java/sopt/motivoo/di/CoroutineModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package sopt.motivoo.di

import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ActivityComponent
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers

@Module
@InstallIn(ActivityComponent::class)
object CoroutineModule {
@Provides
fun provideMainDispatcher(): CoroutineDispatcher = Dispatchers.Main
}
6 changes: 5 additions & 1 deletion app/src/main/java/sopt/motivoo/di/Logger.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,8 @@ import javax.inject.Qualifier

@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class Logger
annotation class AuthInterceptorQualifier

@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class ErrorInterceptorQualifier
21 changes: 21 additions & 0 deletions app/src/main/java/sopt/motivoo/di/NetworkModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package sopt.motivoo.di

import android.content.Context
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import sopt.motivoo.util.NetworkState
import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {

@Provides
@Singleton
fun provideNetworkState(@ApplicationContext context: Context): NetworkState {
return NetworkState(context)
}
}
11 changes: 9 additions & 2 deletions app/src/main/java/sopt/motivoo/di/RepositoryModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import sopt.motivoo.data.repository.AuthRepositoryImpl
import sopt.motivoo.data.repository.DummyRepositoryImpl
import sopt.motivoo.data.repository.OnboardingRepositoryImpl
import sopt.motivoo.data.repository.HomeRepositoryImpl
import sopt.motivoo.data.repository.NetworkRepositoryImpl
import sopt.motivoo.data.repository.OnboardingRepositoryImpl
import sopt.motivoo.domain.repository.AuthRepository
import sopt.motivoo.domain.repository.DummyRepository
import sopt.motivoo.domain.repository.OnboardingRepository
import sopt.motivoo.domain.repository.HomeRepository
import sopt.motivoo.domain.repository.NetworkRepository
import sopt.motivoo.domain.repository.OnboardingRepository
import javax.inject.Singleton

@Module
Expand All @@ -37,4 +39,9 @@ object RepositoryModule {
@Singleton
fun providesOnboardingRepository(onboardingRepositoryImpl: OnboardingRepositoryImpl): OnboardingRepository =
onboardingRepositoryImpl

@Provides
@Singleton
fun providesNetworkRepository(networkRepositoryImpl: NetworkRepositoryImpl): NetworkRepository =
networkRepositoryImpl
}
46 changes: 33 additions & 13 deletions app/src/main/java/sopt/motivoo/di/RetrofitModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@ import retrofit2.Retrofit
import sopt.motivoo.BuildConfig.BASE_URL
import sopt.motivoo.BuildConfig.DEBUG
import sopt.motivoo.data.datasource.local.MotivooStorageImpl
import sopt.motivoo.data.datasource.remote.AuthInterceptor
import sopt.motivoo.data.datasource.remote.intercepter.AuthInterceptor
import sopt.motivoo.data.datasource.remote.intercepter.ErrorInterceptor
import sopt.motivoo.data.datasource.remote.listener.AuthTokenRefreshListener
import sopt.motivoo.data.datasource.remote.listener.AuthTokenRefreshListenerImpl
import sopt.motivoo.data.datasource.remote.listener.NetworkErrorListener
import sopt.motivoo.data.datasource.remote.listener.NetworkErrorListenerImpl
import sopt.motivoo.domain.entity.MotivooStorage
import java.util.concurrent.TimeUnit
import javax.inject.Singleton
Expand All @@ -32,14 +35,36 @@ object RetrofitModule {

@Provides
@Singleton
@Logger
fun provideAuthInterceptor(interceptor: AuthInterceptor): Interceptor = interceptor
@AuthInterceptorQualifier
fun provideAuthInterceptor(authInterceptor: AuthInterceptor): Interceptor = authInterceptor

@Provides
@Singleton
fun provideRefreshListener(authTokenRefreshListenerImpl: AuthTokenRefreshListenerImpl): AuthTokenRefreshListener =
authTokenRefreshListenerImpl

@Provides
@Singleton
@ErrorInterceptorQualifier
fun provideErrorInterceptor(errorInterceptor: ErrorInterceptor): Interceptor = errorInterceptor

@Provides
@Singleton
fun provideNetworkErrorListener(networkErrorListenerImpl: NetworkErrorListenerImpl): NetworkErrorListener =
networkErrorListenerImpl

@Provides
@Singleton
fun providesLoggingInterceptor(): HttpLoggingInterceptor {
return HttpLoggingInterceptor().apply {
level = if (DEBUG) {
HttpLoggingInterceptor.Level.BODY
} else {
HttpLoggingInterceptor.Level.NONE
}
}
}

@Provides
@Singleton
fun provideJson(): Json = Json {
Expand All @@ -52,22 +77,17 @@ object RetrofitModule {
@Provides
@Singleton
fun providesOkHttpClient(
@Logger loggingInterceptor: Interceptor,
loggingInterceptor: HttpLoggingInterceptor,
@AuthInterceptorQualifier authInterceptor: Interceptor,
@ErrorInterceptorQualifier errorInterceptor: Interceptor,
): OkHttpClient =
OkHttpClient.Builder().apply {
connectTimeout(10, TimeUnit.SECONDS)
writeTimeout(10, TimeUnit.SECONDS)
readTimeout(10, TimeUnit.SECONDS)
addInterceptor(authInterceptor)
addInterceptor(errorInterceptor)
addInterceptor(loggingInterceptor)
if (DEBUG) {
addInterceptor(
HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
},
)
} else {
HttpLoggingInterceptor.Level.NONE
}
}.build()

@Provides
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package sopt.motivoo.domain.repository

import kotlinx.coroutines.flow.SharedFlow

interface NetworkRepository {

val networkStateFlow: SharedFlow<Boolean>
val isLoading: SharedFlow<Boolean>
suspend fun setLoading(isLoading: Boolean)
}

This file was deleted.

Loading

0 comments on commit 740cba2

Please sign in to comment.