Skip to content

Commit

Permalink
implement data status
Browse files Browse the repository at this point in the history
  • Loading branch information
ahmedeltaher committed Dec 22, 2019
1 parent 396f958 commit f39dbd5
Show file tree
Hide file tree
Showing 8 changed files with 63 additions and 22 deletions.
3 changes: 1 addition & 2 deletions app/src/main/java/com/task/data/DataRepository.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package com.task.data

import com.task.data.local.LocalRepository
import com.task.data.remote.RemoteRepository
import com.task.data.remote.Data
import javax.inject.Inject


Expand All @@ -13,7 +12,7 @@ import javax.inject.Inject
class DataRepository @Inject
constructor(private val remoteRepository: RemoteRepository, private val localRepository: LocalRepository) : DataSource {

override fun requestNews(): Data? {
override fun requestNews(): DataStatus {
return remoteRepository.requestNews()
}
}
4 changes: 1 addition & 3 deletions app/src/main/java/com/task/data/DataSource.kt
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
package com.task.data

import com.task.data.remote.Data

/**
* Created by ahmedeltaher on 3/23/17.
*/

interface DataSource {
fun requestNews(): Data?
fun requestNews(): DataStatus
}
10 changes: 10 additions & 0 deletions app/src/main/java/com/task/data/DataStatus.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.task.data

import com.task.data.remote.Data
import com.task.data.remote.Error

sealed class DataStatus {
object LoadingState : DataStatus()
class FailureState(val error: Error) : DataStatus()
class SuccessState(val data: Data) : DataStatus()
}
11 changes: 11 additions & 0 deletions app/src/main/java/com/task/data/Resource.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.task.data

// A generic class that contains data and status about loading this data.
sealed class Resource<T>(
val data: T? = null,
val message: String? = null
) {
class Success<T>(data: T) : Resource<T>(data)
class Loading<T>(data: T? = null) : Resource<T>(data)
class Error<T>(message: String, data: T? = null) : Resource<T>(data, message)
}
17 changes: 9 additions & 8 deletions app/src/main/java/com/task/data/remote/RemoteRepository.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.task.data.remote

import com.task.App
import com.task.data.DataStatus
import com.task.data.remote.Error.Companion.NETWORK_ERROR
import com.task.data.remote.service.NewsService
import com.task.utils.Constants
Expand All @@ -18,36 +19,36 @@ import javax.inject.Inject
class RemoteRepository @Inject
constructor(private val serviceGenerator: ServiceGenerator) : RemoteSource {

override fun requestNews(): Data? {
override fun requestNews(): DataStatus {
return if (!isConnected(App.context)) {
Data(Error(code = -1, description = NETWORK_ERROR))
DataStatus.FailureState(Error(code = -1, description = NETWORK_ERROR))
} else {
val newsService = serviceGenerator.createService(NewsService::class.java, Constants.BASE_URL)
processCall(newsService.fetchNews(), false)
}
}

private fun processCall(call: Call<*>, isVoid: Boolean): Data {
private fun processCall(call: Call<*>, isVoid: Boolean): DataStatus {
if (!isConnected(App.context)) {
return Data(Error())
return DataStatus.FailureState(Error())
}
try {
val response = call.execute()
?: return Data(Error(NETWORK_ERROR, ERROR_UNDEFINED))
?: return DataStatus.FailureState(Error(NETWORK_ERROR, ERROR_UNDEFINED))
val responseCode = response.code()
/**
* isVoid is for APIs which reply only with code without any body, such as some Apis
* reply with 200 or 401....
*/
return if (response.isSuccessful) {
val apiResponse: Any? = if (isVoid) null else response.body()
Data(responseCode, apiResponse)
DataStatus.SuccessState(Data(responseCode, apiResponse))
} else {
val serviceError = Error(response.message(), responseCode)
Data(serviceError)
DataStatus.FailureState(serviceError)
}
} catch (e: IOException) {
return Data(Error(NETWORK_ERROR, ERROR_UNDEFINED))
return DataStatus.FailureState(Error(NETWORK_ERROR, ERROR_UNDEFINED))
}

}
Expand Down
4 changes: 3 additions & 1 deletion app/src/main/java/com/task/data/remote/RemoteSource.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package com.task.data.remote

import com.task.data.DataStatus

/**
* Created by ahmedEltaher on 3/23/17.
*/

internal interface RemoteSource {
fun requestNews(): Data?
fun requestNews(): DataStatus
}
33 changes: 25 additions & 8 deletions app/src/main/java/com/task/usecase/NewsUseCase.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package com.task.usecase

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.task.data.DataSource
import com.task.data.remote.Data
import com.task.data.DataStatus
import com.task.data.remote.Error
import com.task.data.remote.Error.Companion.INTERNAL_SERVER_ERROR
import com.task.data.remote.dto.NewsItem
import com.task.data.remote.dto.NewsModel
import com.task.ui.base.listeners.BaseCallback
Expand All @@ -21,17 +22,33 @@ import kotlin.coroutines.CoroutineContext

class NewsUseCase @Inject
constructor(private val dataRepository: DataSource, override val coroutineContext: CoroutineContext) : UseCase, CoroutineScope {
var error: LiveData<Error> = MutableLiveData<Error>()

private val newsMutableLiveData = MutableLiveData<NewsModel>()
override val newsLiveData: LiveData<NewsModel> = newsMutableLiveData

override fun getNews(callback: BaseCallback) {
launch {
try {
val serviceResponse: Data? = withContext(Dispatchers.IO) { dataRepository.requestNews() }
if (serviceResponse?.code == Error.SUCCESS_CODE) {
val data = serviceResponse.data
callback.onSuccess(data as NewsModel)
} else {
callback.onFail(serviceResponse?.error ?: Error(code = INTERNAL_SERVER_ERROR))
val serviceResponse: DataStatus = withContext(Dispatchers.IO) { dataRepository.requestNews() }
when (serviceResponse) {
is DataStatus.LoadingState -> {
}
is DataStatus.SuccessState -> {
callback.onSuccess(serviceResponse.data.data as NewsModel)
// newsMutableLiveData.postValue(serviceResponse.data.data as NewsModel)
}
is DataStatus.FailureState -> {
callback.onFail(serviceResponse.error)
}
}

// if (serviceResponse?.code == Error.SUCCESS_CODE) {
// val data = serviceResponse.data
// callback.onSuccess(data as NewsModel)
// } else {
// callback.onFail(serviceResponse?.error ?: Error(code = INTERNAL_SERVER_ERROR))
// }
} catch (e: Exception) {
callback.onFail(Error(e))
}
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/java/com/task/usecase/UseCase.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.task.usecase

import androidx.lifecycle.LiveData
import com.task.data.remote.dto.NewsItem
import com.task.data.remote.dto.NewsModel
import com.task.ui.base.listeners.BaseCallback

/**
Expand All @@ -11,4 +13,5 @@ interface UseCase {
fun getNews(callback: BaseCallback)

fun searchByTitle(news: List<NewsItem>, keyWord: String): NewsItem?
val newsLiveData: LiveData<NewsModel>
}

0 comments on commit f39dbd5

Please sign in to comment.