Extract server info repo
This commit is contained in:
@@ -1,8 +1,15 @@
|
|||||||
package gq.kirmanak.mealient.data.auth
|
package gq.kirmanak.mealient.data.auth
|
||||||
|
|
||||||
|
import gq.kirmanak.mealient.data.baseurl.ServerVersion
|
||||||
|
|
||||||
interface AuthDataSource {
|
interface AuthDataSource {
|
||||||
/**
|
/**
|
||||||
* Tries to acquire authentication token using the provided credentials
|
* Tries to acquire authentication token using the provided credentials
|
||||||
*/
|
*/
|
||||||
suspend fun authenticate(username: String, password: String, baseUrl: String): String
|
suspend fun authenticate(
|
||||||
|
username: String,
|
||||||
|
password: String,
|
||||||
|
baseUrl: String,
|
||||||
|
serverVersion: ServerVersion,
|
||||||
|
): String
|
||||||
}
|
}
|
||||||
@@ -1,15 +1,25 @@
|
|||||||
package gq.kirmanak.mealient.data.auth.impl
|
package gq.kirmanak.mealient.data.auth.impl
|
||||||
|
|
||||||
import gq.kirmanak.mealient.data.auth.AuthDataSource
|
import gq.kirmanak.mealient.data.auth.AuthDataSource
|
||||||
|
import gq.kirmanak.mealient.data.baseurl.ServerVersion
|
||||||
import gq.kirmanak.mealient.datasource.v0.MealieDataSourceV0
|
import gq.kirmanak.mealient.datasource.v0.MealieDataSourceV0
|
||||||
|
import gq.kirmanak.mealient.datasource.v1.MealieDataSourceV1
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class AuthDataSourceImpl @Inject constructor(
|
class AuthDataSourceImpl @Inject constructor(
|
||||||
private val v0Source: MealieDataSourceV0,
|
private val v0Source: MealieDataSourceV0,
|
||||||
|
private val v1Source: MealieDataSourceV1,
|
||||||
) : AuthDataSource {
|
) : AuthDataSource {
|
||||||
|
|
||||||
override suspend fun authenticate(username: String, password: String, baseUrl: String): String =
|
override suspend fun authenticate(
|
||||||
v0Source.authenticate(baseUrl, username, password)
|
username: String,
|
||||||
|
password: String,
|
||||||
|
baseUrl: String,
|
||||||
|
serverVersion: ServerVersion,
|
||||||
|
): String = when (serverVersion) {
|
||||||
|
ServerVersion.V0 -> v0Source.authenticate(baseUrl, username, password)
|
||||||
|
ServerVersion.V1 -> v1Source.authenticate(baseUrl, username, password)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,7 @@ package gq.kirmanak.mealient.data.auth.impl
|
|||||||
import gq.kirmanak.mealient.data.auth.AuthDataSource
|
import gq.kirmanak.mealient.data.auth.AuthDataSource
|
||||||
import gq.kirmanak.mealient.data.auth.AuthRepo
|
import gq.kirmanak.mealient.data.auth.AuthRepo
|
||||||
import gq.kirmanak.mealient.data.auth.AuthStorage
|
import gq.kirmanak.mealient.data.auth.AuthStorage
|
||||||
import gq.kirmanak.mealient.data.baseurl.BaseURLStorage
|
import gq.kirmanak.mealient.data.baseurl.ServerInfoRepo
|
||||||
import gq.kirmanak.mealient.extensions.runCatchingExceptCancel
|
import gq.kirmanak.mealient.extensions.runCatchingExceptCancel
|
||||||
import gq.kirmanak.mealient.logging.Logger
|
import gq.kirmanak.mealient.logging.Logger
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
@@ -15,7 +15,7 @@ import javax.inject.Singleton
|
|||||||
class AuthRepoImpl @Inject constructor(
|
class AuthRepoImpl @Inject constructor(
|
||||||
private val authStorage: AuthStorage,
|
private val authStorage: AuthStorage,
|
||||||
private val authDataSource: AuthDataSource,
|
private val authDataSource: AuthDataSource,
|
||||||
private val baseURLStorage: BaseURLStorage,
|
private val serverInfoRepo: ServerInfoRepo,
|
||||||
private val logger: Logger,
|
private val logger: Logger,
|
||||||
) : AuthRepo {
|
) : AuthRepo {
|
||||||
|
|
||||||
@@ -24,7 +24,9 @@ class AuthRepoImpl @Inject constructor(
|
|||||||
|
|
||||||
override suspend fun authenticate(email: String, password: String) {
|
override suspend fun authenticate(email: String, password: String) {
|
||||||
logger.v { "authenticate() called with: email = $email, password = $password" }
|
logger.v { "authenticate() called with: email = $email, password = $password" }
|
||||||
authDataSource.authenticate(email, password, baseURLStorage.requireBaseURL())
|
val version = serverInfoRepo.getVersion()
|
||||||
|
val url = serverInfoRepo.requireUrl()
|
||||||
|
authDataSource.authenticate(email, password, url, version)
|
||||||
.let { AUTH_HEADER_FORMAT.format(it) }
|
.let { AUTH_HEADER_FORMAT.format(it) }
|
||||||
.let { authStorage.setAuthHeader(it) }
|
.let { authStorage.setAuthHeader(it) }
|
||||||
authStorage.setEmail(email)
|
authStorage.setEmail(email)
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package gq.kirmanak.mealient.data.baseurl
|
||||||
|
|
||||||
|
interface ServerInfoRepo {
|
||||||
|
|
||||||
|
suspend fun getUrl(): String?
|
||||||
|
|
||||||
|
suspend fun requireUrl(): String
|
||||||
|
|
||||||
|
suspend fun getVersion(): ServerVersion
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package gq.kirmanak.mealient.data.baseurl
|
||||||
|
|
||||||
|
import gq.kirmanak.mealient.datasource.NetworkError
|
||||||
|
import gq.kirmanak.mealient.logging.Logger
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
class ServerInfoRepoImpl @Inject constructor(
|
||||||
|
private val serverInfoStorage: ServerInfoStorage,
|
||||||
|
private val versionDataSource: VersionDataSource,
|
||||||
|
private val logger: Logger,
|
||||||
|
) : ServerInfoRepo {
|
||||||
|
|
||||||
|
override suspend fun getUrl(): String? {
|
||||||
|
val result = serverInfoStorage.getBaseURL()
|
||||||
|
logger.v { "getUrl() returned: $result" }
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun requireUrl(): String {
|
||||||
|
val result = checkNotNull(getUrl()) { "Server URL was null when it was required" }
|
||||||
|
logger.v { "requireUrl() returned: $result" }
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun getVersion(): ServerVersion {
|
||||||
|
var version = serverInfoStorage.getServerVersion()
|
||||||
|
val serverVersion = if (version == null) {
|
||||||
|
logger.d { "getVersion: version is null, requesting" }
|
||||||
|
version = versionDataSource.getVersionInfo(requireUrl()).version
|
||||||
|
val result = determineServerVersion(version)
|
||||||
|
serverInfoStorage.storeServerVersion(version)
|
||||||
|
result
|
||||||
|
} else {
|
||||||
|
determineServerVersion(version)
|
||||||
|
}
|
||||||
|
logger.v { "getVersion() returned: $serverVersion from $version" }
|
||||||
|
return serverVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun determineServerVersion(version: String): ServerVersion = when {
|
||||||
|
version.startsWith("v0") -> ServerVersion.V0
|
||||||
|
version.startsWith("v1") -> ServerVersion.V1
|
||||||
|
else -> throw NetworkError.NotMealie(IllegalStateException("Server version is unknown: $version"))
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,11 +1,9 @@
|
|||||||
package gq.kirmanak.mealient.data.baseurl
|
package gq.kirmanak.mealient.data.baseurl
|
||||||
|
|
||||||
interface BaseURLStorage {
|
interface ServerInfoStorage {
|
||||||
|
|
||||||
suspend fun getBaseURL(): String?
|
suspend fun getBaseURL(): String?
|
||||||
|
|
||||||
suspend fun requireBaseURL(): String
|
|
||||||
|
|
||||||
suspend fun storeBaseURL(baseURL: String, version: String)
|
suspend fun storeBaseURL(baseURL: String, version: String)
|
||||||
|
|
||||||
suspend fun storeServerVersion(version: String)
|
suspend fun storeServerVersion(version: String)
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package gq.kirmanak.mealient.data.baseurl
|
||||||
|
|
||||||
|
enum class ServerVersion { V0, V1 }
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package gq.kirmanak.mealient.data.baseurl
|
||||||
|
|
||||||
|
import gq.kirmanak.mealient.datasource.v0.MealieDataSourceV0
|
||||||
|
import gq.kirmanak.mealient.datasource.v1.MealieDataSourceV1
|
||||||
|
import gq.kirmanak.mealient.extensions.runCatchingExceptCancel
|
||||||
|
import gq.kirmanak.mealient.extensions.toVersionInfo
|
||||||
|
import kotlinx.coroutines.async
|
||||||
|
import kotlinx.coroutines.awaitAll
|
||||||
|
import kotlinx.coroutines.coroutineScope
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
class VersionDataSourceImpl @Inject constructor(
|
||||||
|
private val v0Source: MealieDataSourceV0,
|
||||||
|
private val v1Source: MealieDataSourceV1,
|
||||||
|
) : VersionDataSource {
|
||||||
|
|
||||||
|
override suspend fun getVersionInfo(baseUrl: String): VersionInfo {
|
||||||
|
val responses = coroutineScope {
|
||||||
|
val v0Deferred = async {
|
||||||
|
runCatchingExceptCancel { v0Source.getVersionInfo(baseUrl).toVersionInfo() }
|
||||||
|
}
|
||||||
|
val v1Deferred = async {
|
||||||
|
runCatchingExceptCancel { v1Source.getVersionInfo(baseUrl).toVersionInfo() }
|
||||||
|
}
|
||||||
|
listOf(v0Deferred, v1Deferred).awaitAll()
|
||||||
|
}
|
||||||
|
val firstSuccess = responses.firstNotNullOfOrNull { it.getOrNull() }
|
||||||
|
if (firstSuccess == null) {
|
||||||
|
throw responses.firstNotNullOf { it.exceptionOrNull() }
|
||||||
|
} else {
|
||||||
|
return firstSuccess
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,15 +1,15 @@
|
|||||||
package gq.kirmanak.mealient.data.baseurl.impl
|
package gq.kirmanak.mealient.data.baseurl.impl
|
||||||
|
|
||||||
import androidx.datastore.preferences.core.Preferences
|
import androidx.datastore.preferences.core.Preferences
|
||||||
import gq.kirmanak.mealient.data.baseurl.BaseURLStorage
|
import gq.kirmanak.mealient.data.baseurl.ServerInfoStorage
|
||||||
import gq.kirmanak.mealient.data.storage.PreferencesStorage
|
import gq.kirmanak.mealient.data.storage.PreferencesStorage
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class BaseURLStorageImpl @Inject constructor(
|
class ServerInfoStorageImpl @Inject constructor(
|
||||||
private val preferencesStorage: PreferencesStorage,
|
private val preferencesStorage: PreferencesStorage,
|
||||||
) : BaseURLStorage {
|
) : ServerInfoStorage {
|
||||||
|
|
||||||
private val baseUrlKey: Preferences.Key<String>
|
private val baseUrlKey: Preferences.Key<String>
|
||||||
get() = preferencesStorage.baseUrlKey
|
get() = preferencesStorage.baseUrlKey
|
||||||
@@ -19,10 +19,6 @@ class BaseURLStorageImpl @Inject constructor(
|
|||||||
|
|
||||||
override suspend fun getBaseURL(): String? = getValue(baseUrlKey)
|
override suspend fun getBaseURL(): String? = getValue(baseUrlKey)
|
||||||
|
|
||||||
override suspend fun requireBaseURL(): String = checkNotNull(getBaseURL()) {
|
|
||||||
"Base URL was null when it was required"
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun storeBaseURL(baseURL: String, version: String) {
|
override suspend fun storeBaseURL(baseURL: String, version: String) {
|
||||||
preferencesStorage.storeValues(
|
preferencesStorage.storeValues(
|
||||||
Pair(baseUrlKey, baseURL),
|
Pair(baseUrlKey, baseURL),
|
||||||
@@ -2,9 +2,8 @@ package gq.kirmanak.mealient.data.network
|
|||||||
|
|
||||||
import gq.kirmanak.mealient.data.add.AddRecipeDataSource
|
import gq.kirmanak.mealient.data.add.AddRecipeDataSource
|
||||||
import gq.kirmanak.mealient.data.auth.AuthRepo
|
import gq.kirmanak.mealient.data.auth.AuthRepo
|
||||||
import gq.kirmanak.mealient.data.baseurl.BaseURLStorage
|
import gq.kirmanak.mealient.data.baseurl.ServerInfoRepo
|
||||||
import gq.kirmanak.mealient.data.baseurl.VersionDataSource
|
import gq.kirmanak.mealient.data.baseurl.ServerVersion
|
||||||
import gq.kirmanak.mealient.data.baseurl.VersionInfo
|
|
||||||
import gq.kirmanak.mealient.data.recipes.network.FullRecipeInfo
|
import gq.kirmanak.mealient.data.recipes.network.FullRecipeInfo
|
||||||
import gq.kirmanak.mealient.data.recipes.network.RecipeDataSource
|
import gq.kirmanak.mealient.data.recipes.network.RecipeDataSource
|
||||||
import gq.kirmanak.mealient.data.recipes.network.RecipeSummaryInfo
|
import gq.kirmanak.mealient.data.recipes.network.RecipeSummaryInfo
|
||||||
@@ -12,76 +11,52 @@ import gq.kirmanak.mealient.datasource.NetworkError
|
|||||||
import gq.kirmanak.mealient.datasource.v0.MealieDataSourceV0
|
import gq.kirmanak.mealient.datasource.v0.MealieDataSourceV0
|
||||||
import gq.kirmanak.mealient.datasource.v0.models.AddRecipeRequestV0
|
import gq.kirmanak.mealient.datasource.v0.models.AddRecipeRequestV0
|
||||||
import gq.kirmanak.mealient.datasource.v1.MealieDataSourceV1
|
import gq.kirmanak.mealient.datasource.v1.MealieDataSourceV1
|
||||||
import gq.kirmanak.mealient.extensions.runCatchingExceptCancel
|
|
||||||
import gq.kirmanak.mealient.extensions.toFullRecipeInfo
|
import gq.kirmanak.mealient.extensions.toFullRecipeInfo
|
||||||
import gq.kirmanak.mealient.extensions.toRecipeSummaryInfo
|
import gq.kirmanak.mealient.extensions.toRecipeSummaryInfo
|
||||||
import gq.kirmanak.mealient.extensions.toVersionInfo
|
|
||||||
import kotlinx.coroutines.async
|
|
||||||
import kotlinx.coroutines.awaitAll
|
|
||||||
import kotlinx.coroutines.coroutineScope
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class MealieDataSourceWrapper @Inject constructor(
|
class MealieDataSourceWrapper @Inject constructor(
|
||||||
private val baseURLStorage: BaseURLStorage,
|
private val serverInfoRepo: ServerInfoRepo,
|
||||||
private val authRepo: AuthRepo,
|
private val authRepo: AuthRepo,
|
||||||
private val v0source: MealieDataSourceV0,
|
private val v0source: MealieDataSourceV0,
|
||||||
private val v1Source: MealieDataSourceV1,
|
private val v1Source: MealieDataSourceV1,
|
||||||
) : AddRecipeDataSource, RecipeDataSource, VersionDataSource {
|
) : AddRecipeDataSource, RecipeDataSource {
|
||||||
|
|
||||||
override suspend fun addRecipe(recipe: AddRecipeRequestV0): String =
|
override suspend fun addRecipe(recipe: AddRecipeRequestV0): String = withAuthHeader { token ->
|
||||||
withAuthHeader { token -> v0source.addRecipe(getUrl(), token, recipe) }
|
v0source.addRecipe(getUrl(), token, recipe)
|
||||||
|
|
||||||
override suspend fun getVersionInfo(baseUrl: String): VersionInfo {
|
|
||||||
val responses = coroutineScope {
|
|
||||||
val v0Deferred = async {
|
|
||||||
runCatchingExceptCancel { v0source.getVersionInfo(baseUrl).toVersionInfo() }
|
|
||||||
}
|
|
||||||
val v1Deferred = async {
|
|
||||||
runCatchingExceptCancel { v1Source.getVersionInfo(baseUrl).toVersionInfo() }
|
|
||||||
}
|
|
||||||
listOf(v0Deferred, v1Deferred).awaitAll()
|
|
||||||
}
|
|
||||||
val firstSuccess = responses.firstNotNullOfOrNull { it.getOrNull() }
|
|
||||||
if (firstSuccess == null) {
|
|
||||||
throw responses.firstNotNullOf { it.exceptionOrNull() }
|
|
||||||
} else {
|
|
||||||
return firstSuccess
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun requestRecipes(start: Int, limit: Int): List<RecipeSummaryInfo> =
|
override suspend fun requestRecipes(
|
||||||
withAuthHeader { token ->
|
start: Int,
|
||||||
val url = getUrl()
|
limit: Int
|
||||||
if (isV1()) {
|
): List<RecipeSummaryInfo> = withAuthHeader { token ->
|
||||||
v1Source.requestRecipes(url, token, start, limit).map { it.toRecipeSummaryInfo() }
|
val url = getUrl()
|
||||||
} else {
|
when (getVersion()) {
|
||||||
|
ServerVersion.V0 -> {
|
||||||
v0source.requestRecipes(url, token, start, limit).map { it.toRecipeSummaryInfo() }
|
v0source.requestRecipes(url, token, start, limit).map { it.toRecipeSummaryInfo() }
|
||||||
}
|
}
|
||||||
}
|
ServerVersion.V1 -> {
|
||||||
|
// Imagine start is 30 and limit is 15. It means that we already have page 1 and 2, now we need page 3
|
||||||
override suspend fun requestRecipeInfo(slug: String): FullRecipeInfo =
|
val page = start / limit + 1
|
||||||
withAuthHeader { token ->
|
v1Source.requestRecipes(url, token, page, limit).map { it.toRecipeSummaryInfo() }
|
||||||
val url = getUrl()
|
|
||||||
if (isV1()) {
|
|
||||||
v1Source.requestRecipeInfo(url, token, slug).toFullRecipeInfo()
|
|
||||||
} else {
|
|
||||||
v0source.requestRecipeInfo(url, token, slug).toFullRecipeInfo()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun getUrl() = baseURLStorage.requireBaseURL()
|
|
||||||
|
|
||||||
private suspend fun isV1(): Boolean {
|
|
||||||
var version = baseURLStorage.getServerVersion()
|
|
||||||
if (version == null) {
|
|
||||||
version = getVersionInfo(getUrl()).version
|
|
||||||
baseURLStorage.storeServerVersion(version)
|
|
||||||
}
|
|
||||||
return version.startsWith("v1")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun requestRecipeInfo(slug: String): FullRecipeInfo = withAuthHeader { token ->
|
||||||
|
val url = getUrl()
|
||||||
|
when (getVersion()) {
|
||||||
|
ServerVersion.V0 -> v0source.requestRecipeInfo(url, token, slug).toFullRecipeInfo()
|
||||||
|
ServerVersion.V1 -> v1Source.requestRecipeInfo(url, token, slug).toFullRecipeInfo()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun getUrl() = serverInfoRepo.requireUrl()
|
||||||
|
|
||||||
|
private suspend fun getVersion() = serverInfoRepo.getVersion()
|
||||||
|
|
||||||
private suspend inline fun <T> withAuthHeader(block: (String?) -> T): T =
|
private suspend inline fun <T> withAuthHeader(block: (String?) -> T): T =
|
||||||
runCatching { block(authRepo.getAuthHeader()) }.getOrElse {
|
runCatching { block(authRepo.getAuthHeader()) }.getOrElse {
|
||||||
if (it is NetworkError.Unauthorized) {
|
if (it is NetworkError.Unauthorized) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package gq.kirmanak.mealient.data.recipes.impl
|
package gq.kirmanak.mealient.data.recipes.impl
|
||||||
|
|
||||||
import gq.kirmanak.mealient.data.baseurl.BaseURLStorage
|
import gq.kirmanak.mealient.data.baseurl.ServerInfoRepo
|
||||||
import gq.kirmanak.mealient.logging.Logger
|
import gq.kirmanak.mealient.logging.Logger
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@@ -8,7 +8,7 @@ import javax.inject.Singleton
|
|||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class RecipeImageUrlProviderImpl @Inject constructor(
|
class RecipeImageUrlProviderImpl @Inject constructor(
|
||||||
private val baseURLStorage: BaseURLStorage,
|
private val serverInfoRepo: ServerInfoRepo,
|
||||||
private val logger: Logger,
|
private val logger: Logger,
|
||||||
) : RecipeImageUrlProvider {
|
) : RecipeImageUrlProvider {
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ class RecipeImageUrlProviderImpl @Inject constructor(
|
|||||||
logger.v { "generateImageUrl() called with: slug = $slug" }
|
logger.v { "generateImageUrl() called with: slug = $slug" }
|
||||||
slug?.takeUnless { it.isBlank() } ?: return null
|
slug?.takeUnless { it.isBlank() } ?: return null
|
||||||
val imagePath = IMAGE_PATH_FORMAT.format(slug)
|
val imagePath = IMAGE_PATH_FORMAT.format(slug)
|
||||||
val baseUrl = baseURLStorage.getBaseURL()?.takeUnless { it.isEmpty() }
|
val baseUrl = serverInfoRepo.getUrl()?.takeUnless { it.isEmpty() }
|
||||||
val result = baseUrl?.toHttpUrlOrNull()
|
val result = baseUrl?.toHttpUrlOrNull()
|
||||||
?.newBuilder()
|
?.newBuilder()
|
||||||
?.addPathSegments(imagePath)
|
?.addPathSegments(imagePath)
|
||||||
|
|||||||
@@ -4,10 +4,8 @@ import dagger.Binds
|
|||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.hilt.InstallIn
|
import dagger.hilt.InstallIn
|
||||||
import dagger.hilt.components.SingletonComponent
|
import dagger.hilt.components.SingletonComponent
|
||||||
import gq.kirmanak.mealient.data.baseurl.BaseURLStorage
|
import gq.kirmanak.mealient.data.baseurl.*
|
||||||
import gq.kirmanak.mealient.data.baseurl.VersionDataSource
|
import gq.kirmanak.mealient.data.baseurl.impl.ServerInfoStorageImpl
|
||||||
import gq.kirmanak.mealient.data.baseurl.impl.BaseURLStorageImpl
|
|
||||||
import gq.kirmanak.mealient.data.network.MealieDataSourceWrapper
|
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Module
|
@Module
|
||||||
@@ -16,9 +14,13 @@ interface BaseURLModule {
|
|||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
@Singleton
|
@Singleton
|
||||||
fun bindVersionDataSource(mealieDataSourceWrapper: MealieDataSourceWrapper): VersionDataSource
|
fun bindVersionDataSource(versionDataSourceImpl: VersionDataSourceImpl): VersionDataSource
|
||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
@Singleton
|
@Singleton
|
||||||
fun bindBaseUrlStorage(baseURLStorageImpl: BaseURLStorageImpl): BaseURLStorage
|
fun bindBaseUrlStorage(baseURLStorageImpl: ServerInfoStorageImpl): ServerInfoStorage
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@Singleton
|
||||||
|
fun bindServerInfoRepo(serverInfoRepoImpl: ServerInfoRepoImpl): ServerInfoRepo
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@ import androidx.lifecycle.MutableLiveData
|
|||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import gq.kirmanak.mealient.data.baseurl.BaseURLStorage
|
import gq.kirmanak.mealient.data.baseurl.ServerInfoStorage
|
||||||
import gq.kirmanak.mealient.data.baseurl.VersionDataSource
|
import gq.kirmanak.mealient.data.baseurl.VersionDataSource
|
||||||
import gq.kirmanak.mealient.extensions.runCatchingExceptCancel
|
import gq.kirmanak.mealient.extensions.runCatchingExceptCancel
|
||||||
import gq.kirmanak.mealient.logging.Logger
|
import gq.kirmanak.mealient.logging.Logger
|
||||||
@@ -15,7 +15,7 @@ import javax.inject.Inject
|
|||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class BaseURLViewModel @Inject constructor(
|
class BaseURLViewModel @Inject constructor(
|
||||||
private val baseURLStorage: BaseURLStorage,
|
private val serverInfoStorage: ServerInfoStorage,
|
||||||
private val versionDataSource: VersionDataSource,
|
private val versionDataSource: VersionDataSource,
|
||||||
private val logger: Logger,
|
private val logger: Logger,
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
@@ -36,7 +36,7 @@ class BaseURLViewModel @Inject constructor(
|
|||||||
val result = runCatchingExceptCancel {
|
val result = runCatchingExceptCancel {
|
||||||
// If it returns proper version info then it must be a Mealie
|
// If it returns proper version info then it must be a Mealie
|
||||||
val version = versionDataSource.getVersionInfo(baseURL).version
|
val version = versionDataSource.getVersionInfo(baseURL).version
|
||||||
baseURLStorage.storeBaseURL(baseURL, version)
|
serverInfoStorage.storeBaseURL(baseURL, version)
|
||||||
}
|
}
|
||||||
logger.i { "checkBaseURL: result is $result" }
|
logger.i { "checkBaseURL: result is $result" }
|
||||||
_uiState.value = OperationUiState.fromResult(result)
|
_uiState.value = OperationUiState.fromResult(result)
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import androidx.lifecycle.ViewModel
|
|||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import androidx.navigation.NavDirections
|
import androidx.navigation.NavDirections
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import gq.kirmanak.mealient.data.baseurl.BaseURLStorage
|
import gq.kirmanak.mealient.data.baseurl.ServerInfoRepo
|
||||||
import gq.kirmanak.mealient.data.disclaimer.DisclaimerStorage
|
import gq.kirmanak.mealient.data.disclaimer.DisclaimerStorage
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@@ -15,7 +15,7 @@ import javax.inject.Inject
|
|||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class SplashViewModel @Inject constructor(
|
class SplashViewModel @Inject constructor(
|
||||||
private val disclaimerStorage: DisclaimerStorage,
|
private val disclaimerStorage: DisclaimerStorage,
|
||||||
private val baseURLStorage: BaseURLStorage,
|
private val serverInfoRepo: ServerInfoRepo,
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
private val _nextDestination = MutableLiveData<NavDirections>()
|
private val _nextDestination = MutableLiveData<NavDirections>()
|
||||||
val nextDestination: LiveData<NavDirections> = _nextDestination
|
val nextDestination: LiveData<NavDirections> = _nextDestination
|
||||||
@@ -25,7 +25,7 @@ class SplashViewModel @Inject constructor(
|
|||||||
delay(1000)
|
delay(1000)
|
||||||
_nextDestination.value = when {
|
_nextDestination.value = when {
|
||||||
!disclaimerStorage.isDisclaimerAccepted() -> SplashFragmentDirections.actionSplashFragmentToDisclaimerFragment()
|
!disclaimerStorage.isDisclaimerAccepted() -> SplashFragmentDirections.actionSplashFragmentToDisclaimerFragment()
|
||||||
baseURLStorage.getBaseURL() == null -> SplashFragmentDirections.actionSplashFragmentToBaseURLFragment()
|
serverInfoRepo.getUrl() == null -> SplashFragmentDirections.actionSplashFragmentToBaseURLFragment()
|
||||||
else -> SplashFragmentDirections.actionSplashFragmentToRecipesFragment()
|
else -> SplashFragmentDirections.actionSplashFragmentToRecipesFragment()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import com.google.common.truth.Truth.assertThat
|
|||||||
import gq.kirmanak.mealient.data.auth.AuthDataSource
|
import gq.kirmanak.mealient.data.auth.AuthDataSource
|
||||||
import gq.kirmanak.mealient.data.auth.AuthRepo
|
import gq.kirmanak.mealient.data.auth.AuthRepo
|
||||||
import gq.kirmanak.mealient.data.auth.AuthStorage
|
import gq.kirmanak.mealient.data.auth.AuthStorage
|
||||||
import gq.kirmanak.mealient.data.baseurl.BaseURLStorage
|
import gq.kirmanak.mealient.data.baseurl.ServerInfoStorage
|
||||||
import gq.kirmanak.mealient.logging.Logger
|
import gq.kirmanak.mealient.logging.Logger
|
||||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_AUTH_HEADER
|
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_AUTH_HEADER
|
||||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_BASE_URL
|
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_BASE_URL
|
||||||
@@ -27,7 +27,7 @@ class AuthRepoImplTest {
|
|||||||
lateinit var dataSource: AuthDataSource
|
lateinit var dataSource: AuthDataSource
|
||||||
|
|
||||||
@MockK
|
@MockK
|
||||||
lateinit var baseURLStorage: BaseURLStorage
|
lateinit var serverInfoStorage: ServerInfoStorage
|
||||||
|
|
||||||
@MockK(relaxUnitFun = true)
|
@MockK(relaxUnitFun = true)
|
||||||
lateinit var storage: AuthStorage
|
lateinit var storage: AuthStorage
|
||||||
@@ -40,7 +40,7 @@ class AuthRepoImplTest {
|
|||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
MockKAnnotations.init(this)
|
MockKAnnotations.init(this)
|
||||||
subject = AuthRepoImpl(storage, dataSource, baseURLStorage, logger)
|
subject = AuthRepoImpl(storage, dataSource, serverInfoStorage, logger)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -58,7 +58,7 @@ class AuthRepoImplTest {
|
|||||||
eq(TEST_BASE_URL)
|
eq(TEST_BASE_URL)
|
||||||
)
|
)
|
||||||
} returns TEST_TOKEN
|
} returns TEST_TOKEN
|
||||||
coEvery { baseURLStorage.requireBaseURL() } returns TEST_BASE_URL
|
coEvery { serverInfoStorage.requireBaseURL() } returns TEST_BASE_URL
|
||||||
subject.authenticate(TEST_USERNAME, TEST_PASSWORD)
|
subject.authenticate(TEST_USERNAME, TEST_PASSWORD)
|
||||||
coVerifyAll {
|
coVerifyAll {
|
||||||
storage.setAuthHeader(TEST_AUTH_HEADER)
|
storage.setAuthHeader(TEST_AUTH_HEADER)
|
||||||
@@ -71,7 +71,7 @@ class AuthRepoImplTest {
|
|||||||
@Test
|
@Test
|
||||||
fun `when authenticate fails then does not change storage`() = runTest {
|
fun `when authenticate fails then does not change storage`() = runTest {
|
||||||
coEvery { dataSource.authenticate(any(), any(), any()) } throws RuntimeException()
|
coEvery { dataSource.authenticate(any(), any(), any()) } throws RuntimeException()
|
||||||
coEvery { baseURLStorage.requireBaseURL() } returns TEST_BASE_URL
|
coEvery { serverInfoStorage.requireBaseURL() } returns TEST_BASE_URL
|
||||||
runCatching { subject.authenticate("invalid", "") }
|
runCatching { subject.authenticate("invalid", "") }
|
||||||
confirmVerified(storage)
|
confirmVerified(storage)
|
||||||
}
|
}
|
||||||
@@ -107,7 +107,7 @@ class AuthRepoImplTest {
|
|||||||
fun `when invalidate with credentials then calls authenticate`() = runTest {
|
fun `when invalidate with credentials then calls authenticate`() = runTest {
|
||||||
coEvery { storage.getEmail() } returns TEST_USERNAME
|
coEvery { storage.getEmail() } returns TEST_USERNAME
|
||||||
coEvery { storage.getPassword() } returns TEST_PASSWORD
|
coEvery { storage.getPassword() } returns TEST_PASSWORD
|
||||||
coEvery { baseURLStorage.requireBaseURL() } returns TEST_BASE_URL
|
coEvery { serverInfoStorage.requireBaseURL() } returns TEST_BASE_URL
|
||||||
coEvery {
|
coEvery {
|
||||||
dataSource.authenticate(eq(TEST_USERNAME), eq(TEST_PASSWORD), eq(TEST_BASE_URL))
|
dataSource.authenticate(eq(TEST_USERNAME), eq(TEST_PASSWORD), eq(TEST_BASE_URL))
|
||||||
} returns TEST_TOKEN
|
} returns TEST_TOKEN
|
||||||
@@ -121,7 +121,7 @@ class AuthRepoImplTest {
|
|||||||
fun `when invalidate with credentials and auth fails then clears email`() = runTest {
|
fun `when invalidate with credentials and auth fails then clears email`() = runTest {
|
||||||
coEvery { storage.getEmail() } returns "invalid"
|
coEvery { storage.getEmail() } returns "invalid"
|
||||||
coEvery { storage.getPassword() } returns ""
|
coEvery { storage.getPassword() } returns ""
|
||||||
coEvery { baseURLStorage.requireBaseURL() } returns TEST_BASE_URL
|
coEvery { serverInfoStorage.requireBaseURL() } returns TEST_BASE_URL
|
||||||
coEvery { dataSource.authenticate(any(), any(), any()) } throws RuntimeException()
|
coEvery { dataSource.authenticate(any(), any(), any()) } throws RuntimeException()
|
||||||
subject.invalidateAuthHeader()
|
subject.invalidateAuthHeader()
|
||||||
coVerify { storage.setEmail(null) }
|
coVerify { storage.setEmail(null) }
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package gq.kirmanak.mealient.data.baseurl
|
|||||||
|
|
||||||
import androidx.datastore.preferences.core.stringPreferencesKey
|
import androidx.datastore.preferences.core.stringPreferencesKey
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import gq.kirmanak.mealient.data.baseurl.impl.BaseURLStorageImpl
|
import gq.kirmanak.mealient.data.baseurl.impl.ServerInfoStorageImpl
|
||||||
import gq.kirmanak.mealient.data.storage.PreferencesStorage
|
import gq.kirmanak.mealient.data.storage.PreferencesStorage
|
||||||
import io.mockk.MockKAnnotations
|
import io.mockk.MockKAnnotations
|
||||||
import io.mockk.coEvery
|
import io.mockk.coEvery
|
||||||
@@ -15,19 +15,19 @@ import org.junit.Before
|
|||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
class BaseURLStorageImplTest {
|
class ServerInfoStorageImplTest {
|
||||||
|
|
||||||
@MockK(relaxUnitFun = true)
|
@MockK(relaxUnitFun = true)
|
||||||
lateinit var preferencesStorage: PreferencesStorage
|
lateinit var preferencesStorage: PreferencesStorage
|
||||||
|
|
||||||
lateinit var subject: BaseURLStorage
|
lateinit var subject: ServerInfoStorage
|
||||||
|
|
||||||
private val baseUrlKey = stringPreferencesKey("baseUrlKey")
|
private val baseUrlKey = stringPreferencesKey("baseUrlKey")
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
MockKAnnotations.init(this)
|
MockKAnnotations.init(this)
|
||||||
subject = BaseURLStorageImpl(preferencesStorage)
|
subject = ServerInfoStorageImpl(preferencesStorage)
|
||||||
every { preferencesStorage.baseUrlKey } returns baseUrlKey
|
every { preferencesStorage.baseUrlKey } returns baseUrlKey
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package gq.kirmanak.mealient.data.network
|
package gq.kirmanak.mealient.data.network
|
||||||
|
|
||||||
import gq.kirmanak.mealient.data.auth.AuthRepo
|
import gq.kirmanak.mealient.data.auth.AuthRepo
|
||||||
import gq.kirmanak.mealient.data.baseurl.BaseURLStorage
|
import gq.kirmanak.mealient.data.baseurl.ServerInfoStorage
|
||||||
import gq.kirmanak.mealient.datasource.NetworkError
|
import gq.kirmanak.mealient.datasource.NetworkError
|
||||||
import gq.kirmanak.mealient.datasource.v0.MealieDataSourceV0
|
import gq.kirmanak.mealient.datasource.v0.MealieDataSourceV0
|
||||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_AUTH_HEADER
|
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_AUTH_HEADER
|
||||||
@@ -21,7 +21,7 @@ import java.io.IOException
|
|||||||
class MealieDataSourceV0WrapperTest {
|
class MealieDataSourceV0WrapperTest {
|
||||||
|
|
||||||
@MockK
|
@MockK
|
||||||
lateinit var baseURLStorage: BaseURLStorage
|
lateinit var serverInfoStorage: ServerInfoStorage
|
||||||
|
|
||||||
@MockK(relaxUnitFun = true)
|
@MockK(relaxUnitFun = true)
|
||||||
lateinit var authRepo: AuthRepo
|
lateinit var authRepo: AuthRepo
|
||||||
@@ -34,12 +34,12 @@ class MealieDataSourceV0WrapperTest {
|
|||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
MockKAnnotations.init(this)
|
MockKAnnotations.init(this)
|
||||||
subject = MealieDataSourceWrapper(baseURLStorage, authRepo, mealieDataSourceV0)
|
subject = MealieDataSourceWrapper(serverInfoStorage, authRepo, mealieDataSourceV0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `when withAuthHeader fails with Unauthorized then invalidates auth`() = runTest {
|
fun `when withAuthHeader fails with Unauthorized then invalidates auth`() = runTest {
|
||||||
coEvery { baseURLStorage.requireBaseURL() } returns TEST_BASE_URL
|
coEvery { serverInfoStorage.requireBaseURL() } returns TEST_BASE_URL
|
||||||
coEvery { authRepo.getAuthHeader() } returns null andThen TEST_AUTH_HEADER
|
coEvery { authRepo.getAuthHeader() } returns null andThen TEST_AUTH_HEADER
|
||||||
coEvery {
|
coEvery {
|
||||||
mealieDataSourceV0.requestRecipeInfo(eq(TEST_BASE_URL), isNull(), eq("cake"))
|
mealieDataSourceV0.requestRecipeInfo(eq(TEST_BASE_URL), isNull(), eq("cake"))
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package gq.kirmanak.mealient.data.recipes.impl
|
package gq.kirmanak.mealient.data.recipes.impl
|
||||||
|
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import gq.kirmanak.mealient.data.baseurl.BaseURLStorage
|
import gq.kirmanak.mealient.data.baseurl.ServerInfoStorage
|
||||||
import gq.kirmanak.mealient.logging.Logger
|
import gq.kirmanak.mealient.logging.Logger
|
||||||
import io.mockk.MockKAnnotations
|
import io.mockk.MockKAnnotations
|
||||||
import io.mockk.coEvery
|
import io.mockk.coEvery
|
||||||
@@ -17,7 +17,7 @@ class RecipeImageUrlProviderImplTest {
|
|||||||
lateinit var subject: RecipeImageUrlProvider
|
lateinit var subject: RecipeImageUrlProvider
|
||||||
|
|
||||||
@MockK
|
@MockK
|
||||||
lateinit var baseURLStorage: BaseURLStorage
|
lateinit var serverInfoStorage: ServerInfoStorage
|
||||||
|
|
||||||
@MockK(relaxUnitFun = true)
|
@MockK(relaxUnitFun = true)
|
||||||
lateinit var logger: Logger
|
lateinit var logger: Logger
|
||||||
@@ -25,7 +25,7 @@ class RecipeImageUrlProviderImplTest {
|
|||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
MockKAnnotations.init(this)
|
MockKAnnotations.init(this)
|
||||||
subject = RecipeImageUrlProviderImpl(baseURLStorage, logger)
|
subject = RecipeImageUrlProviderImpl(serverInfoStorage, logger)
|
||||||
prepareBaseURL("https://google.com/")
|
prepareBaseURL("https://google.com/")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,6 +81,6 @@ class RecipeImageUrlProviderImplTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun prepareBaseURL(baseURL: String?) {
|
private fun prepareBaseURL(baseURL: String?) {
|
||||||
coEvery { baseURLStorage.getBaseURL() } returns baseURL
|
coEvery { serverInfoStorage.getBaseURL() } returns baseURL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package gq.kirmanak.mealient.ui.baseurl
|
package gq.kirmanak.mealient.ui.baseurl
|
||||||
|
|
||||||
import gq.kirmanak.mealient.data.baseurl.BaseURLStorage
|
import gq.kirmanak.mealient.data.baseurl.ServerInfoStorage
|
||||||
import gq.kirmanak.mealient.data.baseurl.VersionDataSource
|
import gq.kirmanak.mealient.data.baseurl.VersionDataSource
|
||||||
import gq.kirmanak.mealient.data.baseurl.VersionInfo
|
import gq.kirmanak.mealient.data.baseurl.VersionInfo
|
||||||
import gq.kirmanak.mealient.logging.Logger
|
import gq.kirmanak.mealient.logging.Logger
|
||||||
@@ -21,7 +21,7 @@ import org.junit.Test
|
|||||||
class BaseURLViewModelTest : RobolectricTest() {
|
class BaseURLViewModelTest : RobolectricTest() {
|
||||||
|
|
||||||
@MockK(relaxUnitFun = true)
|
@MockK(relaxUnitFun = true)
|
||||||
lateinit var baseURLStorage: BaseURLStorage
|
lateinit var serverInfoStorage: ServerInfoStorage
|
||||||
|
|
||||||
@MockK
|
@MockK
|
||||||
lateinit var versionDataSource: VersionDataSource
|
lateinit var versionDataSource: VersionDataSource
|
||||||
@@ -34,7 +34,7 @@ class BaseURLViewModelTest : RobolectricTest() {
|
|||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
MockKAnnotations.init(this)
|
MockKAnnotations.init(this)
|
||||||
subject = BaseURLViewModel(baseURLStorage, versionDataSource, logger)
|
subject = BaseURLViewModel(serverInfoStorage, versionDataSource, logger)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -44,6 +44,6 @@ class BaseURLViewModelTest : RobolectricTest() {
|
|||||||
} returns VersionInfo(TEST_VERSION)
|
} returns VersionInfo(TEST_VERSION)
|
||||||
subject.saveBaseUrl(TEST_BASE_URL)
|
subject.saveBaseUrl(TEST_BASE_URL)
|
||||||
advanceUntilIdle()
|
advanceUntilIdle()
|
||||||
coVerify { baseURLStorage.storeBaseURL(eq(TEST_BASE_URL), eq(TEST_VERSION)) }
|
coVerify { serverInfoStorage.storeBaseURL(eq(TEST_BASE_URL), eq(TEST_VERSION)) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -29,8 +29,8 @@ interface MealieDataSourceV1 {
|
|||||||
suspend fun requestRecipes(
|
suspend fun requestRecipes(
|
||||||
baseUrl: String,
|
baseUrl: String,
|
||||||
token: String?,
|
token: String?,
|
||||||
start: Int,
|
page: Int,
|
||||||
limit: Int,
|
perPage: Int,
|
||||||
): List<GetRecipeSummaryResponseV1>
|
): List<GetRecipeSummaryResponseV1>
|
||||||
|
|
||||||
suspend fun requestRecipeInfo(
|
suspend fun requestRecipeInfo(
|
||||||
|
|||||||
@@ -48,18 +48,13 @@ class MealieDataSourceV1Impl @Inject constructor(
|
|||||||
override suspend fun requestRecipes(
|
override suspend fun requestRecipes(
|
||||||
baseUrl: String,
|
baseUrl: String,
|
||||||
token: String?,
|
token: String?,
|
||||||
start: Int,
|
page: Int,
|
||||||
limit: Int
|
perPage: Int
|
||||||
): List<GetRecipeSummaryResponseV1> {
|
): List<GetRecipeSummaryResponseV1> = makeCall(
|
||||||
// Imagine start is 30 and limit is 15. It means that we already have page 1 and 2, now we need page 3
|
block = { getRecipeSummary("$baseUrl/api/recipes", token, page, perPage) },
|
||||||
val perPage = limit
|
logMethod = { "requestRecipesV1" },
|
||||||
val page = start / perPage + 1
|
logParameters = { "baseUrl = $baseUrl, token = $token, page = $page, perPage = $perPage" }
|
||||||
return makeCall(
|
).map { it.items }.getOrThrowUnauthorized()
|
||||||
block = { getRecipeSummary("$baseUrl/api/recipes", token, page, perPage) },
|
|
||||||
logMethod = { "requestRecipesV1" },
|
|
||||||
logParameters = { "baseUrl = $baseUrl, token = $token, start = $start, limit = $limit" }
|
|
||||||
).map { it.items }.getOrThrowUnauthorized()
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun requestRecipeInfo(
|
override suspend fun requestRecipeInfo(
|
||||||
baseUrl: String,
|
baseUrl: String,
|
||||||
|
|||||||
Reference in New Issue
Block a user