Refactor: Migrate network layer from Retrofit to Ktor
This commit migrates the network layer from Retrofit to Ktor. Specific changes include: - Replaced Retrofit with Ktor for network requests. - Updated dependencies to include Ktor libraries. - Refactored network service and data classes to use Ktor's API. - Removed Retrofit-specific code and dependencies. - Adjusted network module to provide Ktor client and services. - Updated Pixabay ImageRepository to use the new Ktor-based PixabayService. - Introduced Result sealed class to handle network responses. - Updated PhotoDetailViewModel to handle Result.Error state.
This commit is contained in:
		| @@ -25,6 +25,8 @@ android { | ||||
| dependencies { | ||||
|     implementation(libs.androidx.paging.compose) | ||||
|  | ||||
|  | ||||
|     //Kotlin Serialization | ||||
|     implementation(libs.kotlinx.serialization.json) | ||||
|  | ||||
|     //Ktor | ||||
|   | ||||
| @@ -0,0 +1,8 @@ | ||||
| package dev.adriankuta.pixabay.data | ||||
|  | ||||
| fun <T> Result<T>.isSuccess() = this is Result.Success<T> | ||||
|  | ||||
| sealed interface Result<out T> { | ||||
|     data class Success<out T>(val data: T) : Result<T> | ||||
|     data class Error(val exception: Throwable) : Result<Nothing> | ||||
| } | ||||
| @@ -31,7 +31,7 @@ internal abstract class NetworkModule { | ||||
|         @Singleton | ||||
|         @Provides | ||||
|         fun provideKtorClient(): HttpClient { | ||||
|             val httpClient = HttpClient(Android) { | ||||
|             return HttpClient(Android) { | ||||
|                 install(ContentNegotiation) { | ||||
|                     json( | ||||
|                         Json { | ||||
| @@ -53,8 +53,6 @@ internal abstract class NetworkModule { | ||||
|                     socketTimeout = 100_000 | ||||
|                 } | ||||
|             } | ||||
|             return httpClient | ||||
|         } | ||||
|  | ||||
|     } | ||||
| } | ||||
| @@ -8,7 +8,6 @@ import dagger.hilt.InstallIn | ||||
| import dagger.hilt.android.qualifiers.ApplicationContext | ||||
| import dagger.hilt.components.SingletonComponent | ||||
| import dev.adriankuta.pixabay.data.room.AppDatabase | ||||
| import dev.adriankuta.pixabay.data.room.dao.PixabayImagesDao | ||||
| import javax.inject.Singleton | ||||
|  | ||||
| @InstallIn(SingletonComponent::class) | ||||
|   | ||||
| @@ -1,6 +1,5 @@ | ||||
| package dev.adriankuta.pixabay.data.dto.response | ||||
|  | ||||
| import io.ktor.resources.Resource | ||||
| import kotlinx.serialization.Serializable | ||||
|  | ||||
| @Serializable | ||||
|   | ||||
| @@ -1,14 +1,15 @@ | ||||
| package dev.adriankuta.pixabay.data.repository | ||||
|  | ||||
| import androidx.paging.PagingData | ||||
| import dev.adriankuta.pixabay.data.Result | ||||
| import dev.adriankuta.pixabay.data.model.PixabayImage | ||||
| import kotlinx.coroutines.flow.Flow | ||||
|  | ||||
| interface ImageRepository { | ||||
|  | ||||
|     suspend fun searchImageById(id: Int): PixabayImage | ||||
|     suspend fun searchImageById(id: Int): Result<PixabayImage> | ||||
|  | ||||
|     suspend fun searchImages(query: String, page: Int, pageSize: Int): List<PixabayImage> | ||||
|     suspend fun searchImages(query: String, page: Int, pageSize: Int): Result<List<PixabayImage>> | ||||
|  | ||||
|     fun getSearchResultStream(query: String): Flow<PagingData<PixabayImage>> | ||||
| } | ||||
| @@ -7,6 +7,7 @@ import androidx.paging.Pager | ||||
| import androidx.paging.PagingConfig | ||||
| import androidx.paging.PagingData | ||||
| import androidx.paging.map | ||||
| import dev.adriankuta.pixabay.data.Result | ||||
| import dev.adriankuta.pixabay.data.model.PixabayImage | ||||
| import dev.adriankuta.pixabay.data.network.PixabayService | ||||
| import dev.adriankuta.pixabay.data.paging.PixabayPagingSource | ||||
| @@ -16,31 +17,38 @@ import kotlinx.coroutines.flow.Flow | ||||
| import kotlinx.coroutines.flow.map | ||||
| import timber.log.Timber | ||||
| import javax.inject.Inject | ||||
| import javax.inject.Named | ||||
|  | ||||
| internal class PixabayImageRepository @Inject constructor( | ||||
|     private val database: AppDatabase, | ||||
|     private val pixabayService: PixabayService | ||||
| ) : ImageRepository { | ||||
|  | ||||
|     override suspend fun searchImageById(id: Int): PixabayImage { | ||||
|     override suspend fun searchImageById(id: Int): Result<PixabayImage> { | ||||
|         return runCatching { | ||||
|             pixabayService.searchImageById(id.toString()) | ||||
|         }.mapCatching { response -> | ||||
|             PixabayImage(response.hits.first()) | ||||
|             Result.Success(PixabayImage(response.hits.first())) | ||||
|         }.onFailure { e -> | ||||
|             Timber.e(e) | ||||
|         }.getOrThrow() | ||||
|         }.getOrElse { | ||||
|             Result.Error(it) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     override suspend fun searchImages(query: String, page: Int, pageSize: Int): List<PixabayImage> { | ||||
|     override suspend fun searchImages( | ||||
|         query: String, | ||||
|         page: Int, | ||||
|         pageSize: Int | ||||
|     ): Result<List<PixabayImage>> { | ||||
|         return runCatching { | ||||
|             pixabayService.searchImages(query, page, pageSize) | ||||
|         }.mapCatching { response -> | ||||
|             response.hits.map { PixabayImage(it) } | ||||
|             Result.Success(response.hits.map { PixabayImage(it) }) | ||||
|         }.onFailure { e -> | ||||
|             Timber.e(e) | ||||
|         }.getOrThrow() | ||||
|         }.getOrElse { | ||||
|             Result.Error(it) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     override fun getSearchResultStream(query: String): Flow<PagingData<PixabayImage>> { | ||||
|   | ||||
| @@ -33,7 +33,7 @@ internal data class PixabayImageEntity( | ||||
|     @ColumnInfo(COLUMN_USER) val user: String, | ||||
|     @ColumnInfo(COLUMN_USER_IMAGE_URL) val userImageURL: String, | ||||
|  | ||||
| ) { | ||||
|     ) { | ||||
|     constructor(pixabayImageResponse: PixabayImageResponse, queryUsed: String) : | ||||
|             this( | ||||
|                 id = pixabayImageResponse.id, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user