Implement core:config module
This commit is contained in:
38
core/config/build.gradle.kts
Normal file
38
core/config/build.gradle.kts
Normal file
@@ -0,0 +1,38 @@
|
||||
plugins {
|
||||
alias(libs.plugins.android.library)
|
||||
alias(libs.plugins.kotlin.android)
|
||||
alias(libs.plugins.kotlin.kapt)
|
||||
alias(libs.plugins.hilt)
|
||||
|
||||
alias(libs.plugins.kotlin.serialization)
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "ru.fincode.tsudesk.core.config"
|
||||
compileSdk = libs.versions.compileSdk.get().toInt()
|
||||
|
||||
defaultConfig {
|
||||
minSdk = libs.versions.minSdk.get().toInt()
|
||||
}
|
||||
val jvm = JavaVersion.toVersion(libs.versions.jvmTarget.get())
|
||||
compileOptions {
|
||||
sourceCompatibility = jvm
|
||||
targetCompatibility = jvm
|
||||
}
|
||||
kotlinOptions {
|
||||
jvmTarget = jvm.toString()
|
||||
}
|
||||
}
|
||||
kapt {
|
||||
correctErrorTypes = true
|
||||
}
|
||||
dependencies {
|
||||
kapt(libs.hilt.compiler)
|
||||
implementation(libs.hilt.android)
|
||||
|
||||
// Kotlin Serialization
|
||||
implementation(libs.kotlinx.serialization.json)
|
||||
|
||||
implementation(project(":core:network"))
|
||||
implementation(project(":core:common"))
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package ru.fincode.tsudesk.core.config.data
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import ru.fincode.tsudesk.core.common.model.DataResult
|
||||
import ru.fincode.tsudesk.core.config.data.datasource.ConfigRemoteDataSource
|
||||
import ru.fincode.tsudesk.core.config.domain.ConfigRepository
|
||||
import ru.fincode.tsudesk.core.config.domain.model.AppConfig
|
||||
import ru.fincode.tsudesk.core.network.model.NetworkResult
|
||||
import javax.inject.Inject
|
||||
|
||||
class ConfigRepositoryImpl @Inject constructor(
|
||||
private val remoteDataSource: ConfigRemoteDataSource
|
||||
) : ConfigRepository {
|
||||
|
||||
private val defaultConfig = AppConfig()
|
||||
|
||||
override suspend fun fetchConfig(): DataResult<AppConfig> {
|
||||
return when (val res = remoteDataSource.load()) {
|
||||
is NetworkResult.Success -> {
|
||||
val dto = res.data
|
||||
DataResult.Data(
|
||||
data = AppConfig(
|
||||
newsEnabled = dto.newsEnabled ?: defaultConfig.newsEnabled,
|
||||
scheduleEnabled = dto.scheduleEnabled ?: defaultConfig.scheduleEnabled,
|
||||
gradesEnabled = dto.gradesEnabled ?: defaultConfig.gradesEnabled
|
||||
),
|
||||
refreshedFromNetwork = true
|
||||
)
|
||||
}
|
||||
|
||||
is NetworkResult.Error -> {
|
||||
DataResult.Error(
|
||||
error = res.error.toAppError(), data = defaultConfig
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun getConfig(): Flow<DataResult<AppConfig>> = flow {
|
||||
when (val result = remoteDataSource.load()) {
|
||||
is NetworkResult.Success -> {
|
||||
val dto = result.data
|
||||
val appConfig = AppConfig(
|
||||
newsEnabled = dto.newsEnabled ?: defaultConfig.newsEnabled,
|
||||
scheduleEnabled = dto.scheduleEnabled ?: defaultConfig.scheduleEnabled,
|
||||
gradesEnabled = dto.gradesEnabled ?: defaultConfig.gradesEnabled
|
||||
)
|
||||
emit(DataResult.Data(data = appConfig, refreshedFromNetwork = true))
|
||||
}
|
||||
|
||||
is NetworkResult.Error -> {
|
||||
emit(
|
||||
DataResult.Error(
|
||||
error = result.error.toAppError(),
|
||||
data = defaultConfig
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package ru.fincode.tsudesk.core.config.data.datasource
|
||||
|
||||
import ru.fincode.tsudesk.core.config.data.remote.dto.RemoteConfigDto
|
||||
import ru.fincode.tsudesk.core.network.model.NetworkResult
|
||||
|
||||
interface ConfigRemoteDataSource {
|
||||
suspend fun load(): NetworkResult<RemoteConfigDto>
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package ru.fincode.tsudesk.core.config.data.datasource
|
||||
|
||||
import ru.fincode.tsudesk.core.config.data.remote.api.ConfigApi
|
||||
import ru.fincode.tsudesk.core.config.data.remote.dto.RemoteConfigDto
|
||||
import ru.fincode.tsudesk.core.network.apiCall
|
||||
import ru.fincode.tsudesk.core.network.model.NetworkResult
|
||||
import javax.inject.Inject
|
||||
|
||||
class ConfigRemoteDataSourceImpl @Inject constructor(
|
||||
private val api: ConfigApi
|
||||
) : ConfigRemoteDataSource {
|
||||
|
||||
override suspend fun load(): NetworkResult<RemoteConfigDto> =
|
||||
apiCall { api.getConfig() }
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package ru.fincode.tsudesk.core.config.data.model
|
||||
|
||||
data class RemoteConfig(
|
||||
val newsEnabled: Boolean,
|
||||
val scheduleEnabled: Boolean,
|
||||
val gradesEnabled: Boolean
|
||||
)
|
||||
@@ -0,0 +1,10 @@
|
||||
package ru.fincode.tsudesk.core.config.data.remote
|
||||
|
||||
object ConfigApiContract {
|
||||
|
||||
const val CONFIG_BASE_URL = "https://scherbatykh.ru/app/tsudesk/"
|
||||
|
||||
object Path {
|
||||
const val GET_CONFIG_METHOD = "config.json"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package ru.fincode.tsudesk.core.config.data.remote.api
|
||||
|
||||
import retrofit2.Response
|
||||
import retrofit2.http.GET
|
||||
import ru.fincode.tsudesk.core.config.data.remote.ConfigApiContract.Path.GET_CONFIG_METHOD
|
||||
import ru.fincode.tsudesk.core.config.data.remote.dto.RemoteConfigDto
|
||||
|
||||
interface ConfigApi {
|
||||
|
||||
@GET(GET_CONFIG_METHOD)
|
||||
suspend fun getConfig(): Response<RemoteConfigDto>
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package ru.fincode.tsudesk.core.config.data.remote.dto
|
||||
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class RemoteConfigDto(
|
||||
val newsEnabled: Boolean? = null,
|
||||
val scheduleEnabled: Boolean? = null,
|
||||
val gradesEnabled: Boolean? = null
|
||||
)
|
||||
@@ -0,0 +1,35 @@
|
||||
package ru.fincode.tsudesk.core.config.di
|
||||
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import okhttp3.OkHttpClient
|
||||
import retrofit2.Retrofit
|
||||
import ru.fincode.tsudesk.core.config.data.remote.ConfigApiContract.CONFIG_BASE_URL
|
||||
import ru.fincode.tsudesk.core.network.RetrofitFactory
|
||||
import ru.fincode.tsudesk.core.config.data.remote.api.ConfigApi
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
object ConfigNetworkModule {
|
||||
@Provides
|
||||
@Singleton
|
||||
@ConfigRetrofit
|
||||
fun provideConfigRetrofit(
|
||||
factory: RetrofitFactory,
|
||||
client: OkHttpClient
|
||||
): Retrofit =
|
||||
factory.create(
|
||||
baseUrl = CONFIG_BASE_URL,
|
||||
client = client
|
||||
)
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideConfigApi(
|
||||
@ConfigRetrofit retrofit: Retrofit
|
||||
): ConfigApi =
|
||||
retrofit.create(ConfigApi::class.java)
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package ru.fincode.tsudesk.core.config.di
|
||||
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import ru.fincode.tsudesk.core.config.data.ConfigRepositoryImpl
|
||||
import ru.fincode.tsudesk.core.config.data.datasource.ConfigRemoteDataSource
|
||||
import ru.fincode.tsudesk.core.config.data.datasource.ConfigRemoteDataSourceImpl
|
||||
import ru.fincode.tsudesk.core.config.domain.ConfigRepository
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
abstract class ConfigRepositoryModule {
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
abstract fun bindRemoteDataSource(
|
||||
impl: ConfigRemoteDataSourceImpl
|
||||
): ConfigRemoteDataSource
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
abstract fun bindRepository(
|
||||
impl: ConfigRepositoryImpl
|
||||
): ConfigRepository
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package ru.fincode.tsudesk.core.config.di
|
||||
|
||||
import javax.inject.Qualifier
|
||||
|
||||
@Qualifier
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
annotation class ConfigRetrofit
|
||||
@@ -0,0 +1,10 @@
|
||||
package ru.fincode.tsudesk.core.config.domain
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import ru.fincode.tsudesk.core.common.model.DataResult
|
||||
import ru.fincode.tsudesk.core.config.domain.model.AppConfig
|
||||
|
||||
interface ConfigRepository {
|
||||
suspend fun fetchConfig(): DataResult<AppConfig>
|
||||
fun getConfig(): Flow<DataResult<AppConfig>>
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package ru.fincode.tsudesk.core.config.domain.model
|
||||
|
||||
data class AppConfig(
|
||||
val newsEnabled: Boolean = false,
|
||||
val scheduleEnabled: Boolean = false,
|
||||
val gradesEnabled: Boolean = false
|
||||
)
|
||||
@@ -0,0 +1,13 @@
|
||||
package ru.fincode.tsudesk.core.config.domain.usecase
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import ru.fincode.tsudesk.core.common.model.DataResult
|
||||
import ru.fincode.tsudesk.core.config.domain.ConfigRepository
|
||||
import ru.fincode.tsudesk.core.config.domain.model.AppConfig
|
||||
import javax.inject.Inject
|
||||
|
||||
class GetConfigUseCase @Inject constructor(
|
||||
private val repository: ConfigRepository
|
||||
) {
|
||||
suspend operator fun invoke(): DataResult<AppConfig> = repository.fetchConfig()
|
||||
}
|
||||
Reference in New Issue
Block a user