Compare commits
	
		
			1 Commits
		
	
	
		
			main
			...
			feature/er
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 3490ee7514 | 
							
								
								
									
										6
									
								
								.idea/AndroidProjectSystem.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										6
									
								
								.idea/AndroidProjectSystem.xml
									
									
									
										generated
									
									
									
								
							| @@ -1,6 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8"?> |  | ||||||
| <project version="4"> |  | ||||||
|   <component name="AndroidProjectSystem"> |  | ||||||
|     <option name="providerId" value="com.android.tools.idea.GradleProjectSystem" /> |  | ||||||
|   </component> |  | ||||||
| </project> |  | ||||||
							
								
								
									
										26
									
								
								.idea/appInsightsSettings.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										26
									
								
								.idea/appInsightsSettings.xml
									
									
									
										generated
									
									
									
								
							| @@ -1,26 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8"?> |  | ||||||
| <project version="4"> |  | ||||||
|   <component name="AppInsightsSettings"> |  | ||||||
|     <option name="tabSettings"> |  | ||||||
|       <map> |  | ||||||
|         <entry key="Firebase Crashlytics"> |  | ||||||
|           <value> |  | ||||||
|             <InsightsFilterSettings> |  | ||||||
|               <option name="connection"> |  | ||||||
|                 <ConnectionSetting> |  | ||||||
|                   <option name="appId" value="PLACEHOLDER" /> |  | ||||||
|                   <option name="mobileSdkAppId" value="" /> |  | ||||||
|                   <option name="projectId" value="" /> |  | ||||||
|                   <option name="projectNumber" value="" /> |  | ||||||
|                 </ConnectionSetting> |  | ||||||
|               </option> |  | ||||||
|               <option name="signal" value="SIGNAL_UNSPECIFIED" /> |  | ||||||
|               <option name="timeIntervalDays" value="THIRTY_DAYS" /> |  | ||||||
|               <option name="visibilityType" value="ALL" /> |  | ||||||
|             </InsightsFilterSettings> |  | ||||||
|           </value> |  | ||||||
|         </entry> |  | ||||||
|       </map> |  | ||||||
|     </option> |  | ||||||
|   </component> |  | ||||||
| </project> |  | ||||||
							
								
								
									
										2
									
								
								.idea/gradle.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								.idea/gradle.xml
									
									
									
										generated
									
									
									
								
							| @@ -16,7 +16,6 @@ | |||||||
|             </builds> |             </builds> | ||||||
|           </compositeBuild> |           </compositeBuild> | ||||||
|         </compositeConfiguration> |         </compositeConfiguration> | ||||||
|         <option name="testRunner" value="CHOOSE_PER_TEST" /> |  | ||||||
|         <option name="externalProjectPath" value="$PROJECT_DIR$" /> |         <option name="externalProjectPath" value="$PROJECT_DIR$" /> | ||||||
|         <option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" /> |         <option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" /> | ||||||
|         <option name="modules"> |         <option name="modules"> | ||||||
| @@ -33,6 +32,7 @@ | |||||||
|             <option value="$PROJECT_DIR$/feature/search" /> |             <option value="$PROJECT_DIR$/feature/search" /> | ||||||
|           </set> |           </set> | ||||||
|         </option> |         </option> | ||||||
|  |         <option name="resolveExternalAnnotations" value="false" /> | ||||||
|       </GradleProjectSettings> |       </GradleProjectSettings> | ||||||
|     </option> |     </option> | ||||||
|   </component> |   </component> | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								.idea/kotlinc.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								.idea/kotlinc.xml
									
									
									
										generated
									
									
									
								
							| @@ -1,6 +1,6 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8"?> | <?xml version="1.0" encoding="UTF-8"?> | ||||||
| <project version="4"> | <project version="4"> | ||||||
|   <component name="KotlinJpsPluginSettings"> |   <component name="KotlinJpsPluginSettings"> | ||||||
|     <option name="version" value="2.1.20" /> |     <option name="version" value="1.9.24" /> | ||||||
|   </component> |   </component> | ||||||
| </project> | </project> | ||||||
							
								
								
									
										3
									
								
								.idea/misc.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										3
									
								
								.idea/misc.xml
									
									
									
										generated
									
									
									
								
							| @@ -1,7 +1,6 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8"?> |  | ||||||
| <project version="4"> | <project version="4"> | ||||||
|   <component name="ExternalStorageConfigurationManager" enabled="true" /> |   <component name="ExternalStorageConfigurationManager" enabled="true" /> | ||||||
|   <component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK"> |   <component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK"> | ||||||
|     <output url="file://$PROJECT_DIR$/build/classes" /> |     <output url="file://$PROJECT_DIR$/build/classes" /> | ||||||
|   </component> |   </component> | ||||||
|   <component name="ProjectType"> |   <component name="ProjectType"> | ||||||
|   | |||||||
							
								
								
									
										17
									
								
								.idea/runConfigurations.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										17
									
								
								.idea/runConfigurations.xml
									
									
									
										generated
									
									
									
								
							| @@ -1,17 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8"?> |  | ||||||
| <project version="4"> |  | ||||||
|   <component name="RunConfigurationProducerService"> |  | ||||||
|     <option name="ignoredProducers"> |  | ||||||
|       <set> |  | ||||||
|         <option value="com.intellij.execution.junit.AbstractAllInDirectoryConfigurationProducer" /> |  | ||||||
|         <option value="com.intellij.execution.junit.AllInPackageConfigurationProducer" /> |  | ||||||
|         <option value="com.intellij.execution.junit.PatternConfigurationProducer" /> |  | ||||||
|         <option value="com.intellij.execution.junit.TestInClassConfigurationProducer" /> |  | ||||||
|         <option value="com.intellij.execution.junit.UniqueIdConfigurationProducer" /> |  | ||||||
|         <option value="com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationProducer" /> |  | ||||||
|         <option value="org.jetbrains.kotlin.idea.junit.KotlinJUnitRunConfigurationProducer" /> |  | ||||||
|         <option value="org.jetbrains.kotlin.idea.junit.KotlinPatternConfigurationProducer" /> |  | ||||||
|       </set> |  | ||||||
|     </option> |  | ||||||
|   </component> |  | ||||||
| </project> |  | ||||||
| @@ -8,7 +8,7 @@ android { | |||||||
|  |  | ||||||
|     defaultConfig { |     defaultConfig { | ||||||
|         applicationId = "dev.adriankuta.pixabay" |         applicationId = "dev.adriankuta.pixabay" | ||||||
|         targetSdk = 35 |         targetSdk = 34 | ||||||
|         versionCode = 1 |         versionCode = 1 | ||||||
|         versionName = "1.0" |         versionName = "1.0" | ||||||
|     } |     } | ||||||
| @@ -23,7 +23,7 @@ android { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     kotlinOptions { |     kotlinOptions { | ||||||
|         jvmTarget = JavaVersion.VERSION_21.toString() |         jvmTarget = JavaVersion.VERSION_17.toString() | ||||||
|     } |     } | ||||||
|     buildFeatures { |     buildFeatures { | ||||||
|         buildConfig = true |         buildConfig = true | ||||||
|   | |||||||
| @@ -21,15 +21,13 @@ plugins { | |||||||
| group = "dev.adriankuta.convention.buildlogic" | group = "dev.adriankuta.convention.buildlogic" | ||||||
|  |  | ||||||
| java { | java { | ||||||
|     sourceCompatibility = JavaVersion.VERSION_21 |     sourceCompatibility = JavaVersion.VERSION_17 | ||||||
|     targetCompatibility = JavaVersion.VERSION_21 |     targetCompatibility = JavaVersion.VERSION_17 | ||||||
| } | } | ||||||
|  |  | ||||||
| dependencies { | dependencies { | ||||||
|     compileOnly(libs.android.gradlePlugin) |     compileOnly(libs.android.tools.build.gradle.plugin) | ||||||
|     compileOnly(libs.compose.gradlePlugin) |     compileOnly(libs.kotlin.gradle.plugin) | ||||||
|     compileOnly(libs.kotlin.gradlePlugin) |  | ||||||
|     compileOnly(libs.ksp.gradlePlugin) |  | ||||||
| } | } | ||||||
|  |  | ||||||
| gradlePlugin { | gradlePlugin { | ||||||
|   | |||||||
| @@ -7,7 +7,6 @@ import org.gradle.kotlin.dsl.getByType | |||||||
| class ComposeConventionPlugin : Plugin<Project> { | class ComposeConventionPlugin : Plugin<Project> { | ||||||
|     override fun apply(target: Project) { |     override fun apply(target: Project) { | ||||||
|         with(target) { |         with(target) { | ||||||
|  |  | ||||||
|             val extension = extensions.getByType<BaseExtension>() |             val extension = extensions.getByType<BaseExtension>() | ||||||
|             configureCompose(extension) |             configureCompose(extension) | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -6,7 +6,7 @@ import org.gradle.api.JavaVersion | |||||||
| @Suppress("UnstableApiUsage") | @Suppress("UnstableApiUsage") | ||||||
| internal fun configureAndroid(commonExtension: CommonExtension<*, *, *, *, *>) { | internal fun configureAndroid(commonExtension: CommonExtension<*, *, *, *, *>) { | ||||||
|     commonExtension.apply { |     commonExtension.apply { | ||||||
|         compileSdk = 35 |         compileSdk = 34 | ||||||
|  |  | ||||||
|         defaultConfig { |         defaultConfig { | ||||||
|             minSdk = 24 |             minSdk = 24 | ||||||
| @@ -19,8 +19,8 @@ internal fun configureAndroid(commonExtension: CommonExtension<*, *, *, *, *>) { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         compileOptions { |         compileOptions { | ||||||
|             sourceCompatibility = JavaVersion.VERSION_21 |             sourceCompatibility = JavaVersion.VERSION_17 | ||||||
|             targetCompatibility = JavaVersion.VERSION_21 |             targetCompatibility = JavaVersion.VERSION_17 | ||||||
|         } |         } | ||||||
|         packaging { |         packaging { | ||||||
|             resources { |             resources { | ||||||
|   | |||||||
| @@ -4,12 +4,8 @@ import com.android.build.gradle.BaseExtension | |||||||
| import org.gradle.api.Project | import org.gradle.api.Project | ||||||
| import org.gradle.api.artifacts.VersionCatalog | import org.gradle.api.artifacts.VersionCatalog | ||||||
| import org.gradle.api.artifacts.VersionCatalogsExtension | import org.gradle.api.artifacts.VersionCatalogsExtension | ||||||
| import org.gradle.kotlin.dsl.assign |  | ||||||
| import org.gradle.kotlin.dsl.configure |  | ||||||
| import org.gradle.kotlin.dsl.dependencies | import org.gradle.kotlin.dsl.dependencies | ||||||
| import org.gradle.kotlin.dsl.getByType | import org.gradle.kotlin.dsl.getByType | ||||||
| import org.jetbrains.kotlin.compose.compiler.gradle.ComposeCompilerGradlePluginExtension |  | ||||||
| import kotlin.with |  | ||||||
|  |  | ||||||
| @Suppress("UnstableApiUsage") | @Suppress("UnstableApiUsage") | ||||||
| internal fun Project.configureCompose(commonExtension: BaseExtension) { | internal fun Project.configureCompose(commonExtension: BaseExtension) { | ||||||
| @@ -18,15 +14,8 @@ internal fun Project.configureCompose(commonExtension: BaseExtension) { | |||||||
|             compose = true |             compose = true | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         with(pluginManager) { |  | ||||||
|             apply("org.jetbrains.kotlin.plugin.compose") |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         val libs: VersionCatalog = extensions.getByType<VersionCatalogsExtension>().named("libs") |         val libs: VersionCatalog = extensions.getByType<VersionCatalogsExtension>().named("libs") | ||||||
|  |  | ||||||
|         /*extensions.configure<ComposeCompilerGradlePluginExtension> { |  | ||||||
|         }*/ |  | ||||||
|  |  | ||||||
|         composeOptions { |         composeOptions { | ||||||
|             kotlinCompilerExtensionVersion = |             kotlinCompilerExtensionVersion = | ||||||
|                 libs.findVersion("composeCompiler").get().toString() |                 libs.findVersion("composeCompiler").get().toString() | ||||||
|   | |||||||
| @@ -4,5 +4,4 @@ plugins { | |||||||
|     alias(libs.plugins.kotlin.android) apply false |     alias(libs.plugins.kotlin.android) apply false | ||||||
|     alias(libs.plugins.hilt) apply false |     alias(libs.plugins.hilt) apply false | ||||||
|     alias(libs.plugins.ksp) apply false |     alias(libs.plugins.ksp) apply false | ||||||
|     alias(libs.plugins.compose.compiler) apply false |  | ||||||
| } | } | ||||||
| @@ -3,7 +3,7 @@ | |||||||
|     android:height="24dp" |     android:height="24dp" | ||||||
|     android:viewportWidth="960" |     android:viewportWidth="960" | ||||||
|     android:viewportHeight="960"> |     android:viewportHeight="960"> | ||||||
|   <path |     <path | ||||||
|       android:pathData="M280,560h400q17,0 28.5,-11.5T720,520q0,-17 -11.5,-28.5T680,480L280,480q-17,0 -28.5,11.5T240,520q0,17 11.5,28.5T280,560ZM280,440h400q17,0 28.5,-11.5T720,400q0,-17 -11.5,-28.5T680,360L280,360q-17,0 -28.5,11.5T240,400q0,17 11.5,28.5T280,440ZM280,320h400q17,0 28.5,-11.5T720,280q0,-17 -11.5,-28.5T680,240L280,240q-17,0 -28.5,11.5T240,280q0,17 11.5,28.5T280,320ZM160,720q-33,0 -56.5,-23.5T80,640v-480q0,-33 23.5,-56.5T160,80h640q33,0 56.5,23.5T880,160v623q0,27 -24.5,37.5T812,812l-92,-92L160,720ZM754,640 L800,685v-525L160,160v480h594ZM160,640v-480,480Z" |         android:fillColor="#5f6368" | ||||||
|       android:fillColor="#5f6368"/> |         android:pathData="M280,560h400q17,0 28.5,-11.5T720,520q0,-17 -11.5,-28.5T680,480L280,480q-17,0 -28.5,11.5T240,520q0,17 11.5,28.5T280,560ZM280,440h400q17,0 28.5,-11.5T720,400q0,-17 -11.5,-28.5T680,360L280,360q-17,0 -28.5,11.5T240,400q0,17 11.5,28.5T280,440ZM280,320h400q17,0 28.5,-11.5T720,280q0,-17 -11.5,-28.5T680,240L280,240q-17,0 -28.5,11.5T240,280q0,17 11.5,28.5T280,320ZM160,720q-33,0 -56.5,-23.5T80,640v-480q0,-33 23.5,-56.5T160,80h640q33,0 56.5,23.5T880,160v623q0,27 -24.5,37.5T812,812l-92,-92L160,720ZM754,640 L800,685v-525L160,160v480h594ZM160,640v-480,480Z" /> | ||||||
| </vector> | </vector> | ||||||
|   | |||||||
| @@ -3,7 +3,7 @@ | |||||||
|     android:height="24dp" |     android:height="24dp" | ||||||
|     android:viewportWidth="960" |     android:viewportWidth="960" | ||||||
|     android:viewportHeight="960"> |     android:viewportHeight="960"> | ||||||
|   <path |     <path | ||||||
|       android:pathData="M480,623q-8,0 -15,-2.5t-13,-8.5L308,468q-12,-12 -11.5,-28t11.5,-28q12,-12 28.5,-12.5T365,411l75,75v-286q0,-17 11.5,-28.5T480,160q17,0 28.5,11.5T520,200v286l75,-75q12,-12 28.5,-11.5T652,412q11,12 11.5,28T652,468L508,612q-6,6 -13,8.5t-15,2.5ZM240,800q-33,0 -56.5,-23.5T160,720v-80q0,-17 11.5,-28.5T200,600q17,0 28.5,11.5T240,640v80h480v-80q0,-17 11.5,-28.5T760,600q17,0 28.5,11.5T800,640v80q0,33 -23.5,56.5T720,800L240,800Z" |         android:fillColor="#5f6368" | ||||||
|       android:fillColor="#5f6368"/> |         android:pathData="M480,623q-8,0 -15,-2.5t-13,-8.5L308,468q-12,-12 -11.5,-28t11.5,-28q12,-12 28.5,-12.5T365,411l75,75v-286q0,-17 11.5,-28.5T480,160q17,0 28.5,11.5T520,200v286l75,-75q12,-12 28.5,-11.5T652,412q11,12 11.5,28T652,468L508,612q-6,6 -13,8.5t-15,2.5ZM240,800q-33,0 -56.5,-23.5T160,720v-80q0,-17 11.5,-28.5T200,600q17,0 28.5,11.5T240,640v80h480v-80q0,-17 11.5,-28.5T760,600q17,0 28.5,11.5T800,640v80q0,33 -23.5,56.5T720,800L240,800Z" /> | ||||||
| </vector> | </vector> | ||||||
|   | |||||||
| @@ -25,6 +25,8 @@ android { | |||||||
| dependencies { | dependencies { | ||||||
|     implementation(libs.androidx.paging.compose) |     implementation(libs.androidx.paging.compose) | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     //Kotlin Serialization | ||||||
|     implementation(libs.kotlinx.serialization.json) |     implementation(libs.kotlinx.serialization.json) | ||||||
|  |  | ||||||
|     //Ktor |     //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 |         @Singleton | ||||||
|         @Provides |         @Provides | ||||||
|         fun provideKtorClient(): HttpClient { |         fun provideKtorClient(): HttpClient { | ||||||
|             val httpClient = HttpClient(Android) { |             return HttpClient(Android) { | ||||||
|                 install(ContentNegotiation) { |                 install(ContentNegotiation) { | ||||||
|                     json( |                     json( | ||||||
|                         Json { |                         Json { | ||||||
| @@ -53,8 +53,6 @@ internal abstract class NetworkModule { | |||||||
|                     socketTimeout = 100_000 |                     socketTimeout = 100_000 | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             return httpClient |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -8,7 +8,6 @@ import dagger.hilt.InstallIn | |||||||
| import dagger.hilt.android.qualifiers.ApplicationContext | import dagger.hilt.android.qualifiers.ApplicationContext | ||||||
| import dagger.hilt.components.SingletonComponent | import dagger.hilt.components.SingletonComponent | ||||||
| import dev.adriankuta.pixabay.data.room.AppDatabase | import dev.adriankuta.pixabay.data.room.AppDatabase | ||||||
| import dev.adriankuta.pixabay.data.room.dao.PixabayImagesDao |  | ||||||
| import javax.inject.Singleton | import javax.inject.Singleton | ||||||
|  |  | ||||||
| @InstallIn(SingletonComponent::class) | @InstallIn(SingletonComponent::class) | ||||||
|   | |||||||
| @@ -1,6 +1,5 @@ | |||||||
| package dev.adriankuta.pixabay.data.dto.response | package dev.adriankuta.pixabay.data.dto.response | ||||||
|  |  | ||||||
| import io.ktor.resources.Resource |  | ||||||
| import kotlinx.serialization.Serializable | import kotlinx.serialization.Serializable | ||||||
|  |  | ||||||
| @Serializable | @Serializable | ||||||
|   | |||||||
| @@ -1,14 +1,15 @@ | |||||||
| package dev.adriankuta.pixabay.data.repository | package dev.adriankuta.pixabay.data.repository | ||||||
|  |  | ||||||
| import androidx.paging.PagingData | import androidx.paging.PagingData | ||||||
|  | import dev.adriankuta.pixabay.data.Result | ||||||
| import dev.adriankuta.pixabay.data.model.PixabayImage | import dev.adriankuta.pixabay.data.model.PixabayImage | ||||||
| import kotlinx.coroutines.flow.Flow | import kotlinx.coroutines.flow.Flow | ||||||
|  |  | ||||||
| interface ImageRepository { | 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>> |     fun getSearchResultStream(query: String): Flow<PagingData<PixabayImage>> | ||||||
| } | } | ||||||
| @@ -7,6 +7,7 @@ import androidx.paging.Pager | |||||||
| import androidx.paging.PagingConfig | import androidx.paging.PagingConfig | ||||||
| import androidx.paging.PagingData | import androidx.paging.PagingData | ||||||
| import androidx.paging.map | import androidx.paging.map | ||||||
|  | import dev.adriankuta.pixabay.data.Result | ||||||
| import dev.adriankuta.pixabay.data.model.PixabayImage | import dev.adriankuta.pixabay.data.model.PixabayImage | ||||||
| import dev.adriankuta.pixabay.data.network.PixabayService | import dev.adriankuta.pixabay.data.network.PixabayService | ||||||
| import dev.adriankuta.pixabay.data.paging.PixabayPagingSource | import dev.adriankuta.pixabay.data.paging.PixabayPagingSource | ||||||
| @@ -16,31 +17,38 @@ import kotlinx.coroutines.flow.Flow | |||||||
| import kotlinx.coroutines.flow.map | import kotlinx.coroutines.flow.map | ||||||
| import timber.log.Timber | import timber.log.Timber | ||||||
| import javax.inject.Inject | import javax.inject.Inject | ||||||
| import javax.inject.Named |  | ||||||
|  |  | ||||||
| internal class PixabayImageRepository @Inject constructor( | internal class PixabayImageRepository @Inject constructor( | ||||||
|     private val database: AppDatabase, |     private val database: AppDatabase, | ||||||
|     private val pixabayService: PixabayService |     private val pixabayService: PixabayService | ||||||
| ) : ImageRepository { | ) : ImageRepository { | ||||||
|  |  | ||||||
|     override suspend fun searchImageById(id: Int): PixabayImage { |     override suspend fun searchImageById(id: Int): Result<PixabayImage> { | ||||||
|         return runCatching { |         return runCatching { | ||||||
|             pixabayService.searchImageById(id.toString()) |             pixabayService.searchImageById(id.toString()) | ||||||
|         }.mapCatching { response -> |         }.mapCatching { response -> | ||||||
|             PixabayImage(response.hits.first()) |             Result.Success(PixabayImage(response.hits.first())) | ||||||
|         }.onFailure { e -> |         }.onFailure { e -> | ||||||
|             Timber.e(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 { |         return runCatching { | ||||||
|             pixabayService.searchImages(query, page, pageSize) |             pixabayService.searchImages(query, page, pageSize) | ||||||
|         }.mapCatching { response -> |         }.mapCatching { response -> | ||||||
|             response.hits.map { PixabayImage(it) } |             Result.Success(response.hits.map { PixabayImage(it) }) | ||||||
|         }.onFailure { e -> |         }.onFailure { e -> | ||||||
|             Timber.e(e) |             Timber.e(e) | ||||||
|         }.getOrThrow() |         }.getOrElse { | ||||||
|  |             Result.Error(it) | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     override fun getSearchResultStream(query: String): Flow<PagingData<PixabayImage>> { |     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) val user: String, | ||||||
|     @ColumnInfo(COLUMN_USER_IMAGE_URL) val userImageURL: String, |     @ColumnInfo(COLUMN_USER_IMAGE_URL) val userImageURL: String, | ||||||
|  |  | ||||||
| ) { |     ) { | ||||||
|     constructor(pixabayImageResponse: PixabayImageResponse, queryUsed: String) : |     constructor(pixabayImageResponse: PixabayImageResponse, queryUsed: String) : | ||||||
|             this( |             this( | ||||||
|                 id = pixabayImageResponse.id, |                 id = pixabayImageResponse.id, | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ import androidx.lifecycle.viewModelScope | |||||||
| import dagger.assisted.Assisted | import dagger.assisted.Assisted | ||||||
| import dagger.assisted.AssistedInject | import dagger.assisted.AssistedInject | ||||||
| import dagger.hilt.android.lifecycle.HiltViewModel | import dagger.hilt.android.lifecycle.HiltViewModel | ||||||
|  | import dev.adriankuta.pixabay.data.Result | ||||||
| import dev.adriankuta.pixabay.data.repository.ImageRepository | import dev.adriankuta.pixabay.data.repository.ImageRepository | ||||||
| import dev.adriankuta.pixabay.feature.details.di.PhotoDetailsViewModelFactory | import dev.adriankuta.pixabay.feature.details.di.PhotoDetailsViewModelFactory | ||||||
| import kotlinx.coroutines.flow.SharingStarted | import kotlinx.coroutines.flow.SharingStarted | ||||||
| @@ -23,7 +24,12 @@ class PhotoDetailViewModel @AssistedInject constructor( | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     val uiState = loadedData |     val uiState = loadedData | ||||||
|         .map { PhotoDetailUiState.Success(it) } |         .map { | ||||||
|  |             when (it) { | ||||||
|  |                 is Result.Success -> PhotoDetailUiState.Success(it.data) | ||||||
|  |                 is Result.Error -> PhotoDetailUiState.Error | ||||||
|  |             } | ||||||
|  |         } | ||||||
|         .stateIn( |         .stateIn( | ||||||
|             scope = viewModelScope, |             scope = viewModelScope, | ||||||
|             started = SharingStarted.WhileSubscribed(stopTimeoutMillis = 5000), |             started = SharingStarted.WhileSubscribed(stopTimeoutMillis = 5000), | ||||||
|   | |||||||
| @@ -17,7 +17,6 @@ import androidx.compose.ui.Modifier | |||||||
| import androidx.compose.ui.layout.ContentScale | import androidx.compose.ui.layout.ContentScale | ||||||
| import androidx.compose.ui.platform.testTag | import androidx.compose.ui.platform.testTag | ||||||
| import androidx.compose.ui.res.stringResource | import androidx.compose.ui.res.stringResource | ||||||
| import androidx.compose.ui.tooling.preview.Preview |  | ||||||
| import androidx.compose.ui.unit.dp | import androidx.compose.ui.unit.dp | ||||||
| import androidx.hilt.navigation.compose.hiltViewModel | import androidx.hilt.navigation.compose.hiltViewModel | ||||||
| import androidx.paging.LoadState | import androidx.paging.LoadState | ||||||
|   | |||||||
| @@ -1,7 +1,5 @@ | |||||||
| package dev.adriankuta.pixabay.feature.search | package dev.adriankuta.pixabay.feature.search | ||||||
|  |  | ||||||
| import dev.adriankuta.pixabay.data.model.PixabayImage |  | ||||||
|  |  | ||||||
|  |  | ||||||
| data class SearchUiState( | data class SearchUiState( | ||||||
|     val query: String = "" |     val query: String = "" | ||||||
|   | |||||||
| @@ -1,82 +1,77 @@ | |||||||
| [versions] | [versions] | ||||||
| androidxNavigation = "2.8.9" | androidxNavigation = "2.7.7" | ||||||
| androidGradlePlugin = "8.1.4" | androidGradlePlugin = "8.1.4" | ||||||
| agp = "8.6.1" | agp = "8.6.0-rc01" | ||||||
| coilCompose = "2.7.0" | coilCompose = "2.6.0" | ||||||
| composeCompiler = "1.5.15" | composeCompiler = "1.5.14" | ||||||
| kotlin = "2.1.20" | kotlin = "1.9.24" | ||||||
| kotlinSerialization = "2.0.0" | kotlinSerialization = "2.0.0" | ||||||
| coreKtx = "1.16.0" | coreKtx = "1.13.1" | ||||||
| androidxHilt = "1.2.0" | androidxHilt = "1.2.0" | ||||||
| junit = "4.13.2" | junit = "4.13.2" | ||||||
| junitVersion = "1.2.1" | junitVersion = "1.2.1" | ||||||
| espressoCore = "3.6.1" | espressoCore = "3.6.1" | ||||||
| androidxLifecycle = "2.8.7" | androidxLifecycle = "2.8.3" | ||||||
| activityCompose = "1.10.1" | activityCompose = "1.9.0" | ||||||
| composeBom = "2025.04.01" | composeBom = "2024.06.00" | ||||||
| kotlinxSerializationJson = "1.8.0" | kotlinxSerializationJson = "1.6.0" | ||||||
| ktor = "2.3.12" | ktor = "2.3.12" | ||||||
| okhttpBom = "4.12.0" | okhttpBom = "4.12.0" | ||||||
| pagingCompose = "3.3.6" | pagingCompose = "3.3.0" | ||||||
| room = "2.7.1" | room = "2.6.1" | ||||||
| slf4jAndroid = "1.7.36" | slf4jAndroid = "1.7.36" | ||||||
| timber = "5.0.1" | timber = "5.0.1" | ||||||
| hilt = "2.54" | hilt = "2.51.1" | ||||||
| ksp = "2.1.20-2.0.0" | ksp = "1.9.24-1.0.20" | ||||||
|  |  | ||||||
| [libraries] | [libraries] | ||||||
| androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" } | android-tools-build-gradle-plugin = { group = "com.android.tools.build", name = "gradle", version.ref = "androidGradlePlugin" } | ||||||
| androidx-compiler = { module = "androidx.compose.compiler:compiler", version.ref = "composeCompiler" } | androidx-compiler = { module = "androidx.compose.compiler:compiler", version.ref = "composeCompiler" } | ||||||
| androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" } |  | ||||||
| androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } | androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } | ||||||
| androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" } |  | ||||||
| androidx-hilt-navigation-compose = { group = "androidx.hilt", name = "hilt-navigation-compose", version.ref = "androidxHilt" } | androidx-hilt-navigation-compose = { group = "androidx.hilt", name = "hilt-navigation-compose", version.ref = "androidxHilt" } | ||||||
| androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" } |  | ||||||
| androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "androidxLifecycle" } |  | ||||||
| androidx-lifecycle-viewmodel-compose = { module = "androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "androidxLifecycle" } |  | ||||||
| androidx-material3 = { group = "androidx.compose.material3", name = "material3" } |  | ||||||
| androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "androidxNavigation" } |  | ||||||
| androidx-paging-compose = { group = "androidx.paging", name = "paging-compose", version.ref = "pagingCompose" } | androidx-paging-compose = { group = "androidx.paging", name = "paging-compose", version.ref = "pagingCompose" } | ||||||
| androidx-room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" } | androidx-room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" } | ||||||
|  | androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" } | ||||||
| androidx-room-ktx = { group = "androidx.room", name = "room-ktx", version.ref = "room" } | androidx-room-ktx = { group = "androidx.room", name = "room-ktx", version.ref = "room" } | ||||||
| androidx-room-paging = { group = "androidx.room", name = "room-paging", version.ref = "room" } | androidx-room-paging = { group = "androidx.room", name = "room-paging", version.ref = "room" } | ||||||
| androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" } | coil-compose = { module = "io.coil-kt:coil-compose", version.ref = "coilCompose" } | ||||||
|  | kotlin-gradle-plugin = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-plugin", version.ref = "kotlin" } | ||||||
|  | junit = { group = "junit", name = "junit", version.ref = "junit" } | ||||||
|  | androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" } | ||||||
|  | androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" } | ||||||
|  | androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "androidxLifecycle" } | ||||||
|  | androidx-lifecycle-viewmodel-compose = { module = "androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "androidxLifecycle" } | ||||||
|  | androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" } | ||||||
|  | androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" } | ||||||
|  | androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "androidxNavigation" } | ||||||
| androidx-ui = { group = "androidx.compose.ui", name = "ui" } | androidx-ui = { group = "androidx.compose.ui", name = "ui" } | ||||||
| androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" } | androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" } | ||||||
| androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" } |  | ||||||
| androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" } |  | ||||||
| androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" } | androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" } | ||||||
| androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" } | androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" } | ||||||
| coil-compose = { module = "io.coil-kt:coil-compose", version.ref = "coilCompose" } | androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" } | ||||||
| hilt-android = { group = "com.google.dagger", name = "hilt-android", version.ref = "hilt" } | androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" } | ||||||
| hilt-compiler = { group = "com.google.dagger", name = "hilt-compiler", version.ref = "hilt" } | androidx-material3 = { group = "androidx.compose.material3", name = "material3" } | ||||||
| junit = { group = "junit", name = "junit", version.ref = "junit" } |  | ||||||
| kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinxSerializationJson" } | kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinxSerializationJson" } | ||||||
| ktor-client-android = { group = "io.ktor", name = "ktor-client-android", version.ref = "ktor" } | ktor-client-android = { group = "io.ktor", name = "ktor-client-android", version.ref = "ktor" } | ||||||
|  | ktor-client-resources = { group = "io.ktor", name = "ktor-client-resources", version.ref = "ktor" } | ||||||
| ktor-client-content-negotiation = { group = "io.ktor", name = "ktor-client-content-negotiation", version.ref = "ktor" } | ktor-client-content-negotiation = { group = "io.ktor", name = "ktor-client-content-negotiation", version.ref = "ktor" } | ||||||
| ktor-client-logging = { group = "io.ktor", name = "ktor-client-logging", version.ref = "ktor" } | ktor-client-logging = { group = "io.ktor", name = "ktor-client-logging", version.ref = "ktor" } | ||||||
| ktor-client-resources = { group = "io.ktor", name = "ktor-client-resources", version.ref = "ktor" } |  | ||||||
| ktor-serialization-kotlinx-json = { group = "io.ktor", name = "ktor-serialization-kotlinx-json", version.ref = "ktor" } | ktor-serialization-kotlinx-json = { group = "io.ktor", name = "ktor-serialization-kotlinx-json", version.ref = "ktor" } | ||||||
| logging-interceptor = { module = "com.squareup.okhttp3:logging-interceptor" } | logging-interceptor = { module = "com.squareup.okhttp3:logging-interceptor" } | ||||||
| okhttp = { module = "com.squareup.okhttp3:okhttp" } | okhttp = { module = "com.squareup.okhttp3:okhttp" } | ||||||
| okhttp-bom = { module = "com.squareup.okhttp3:okhttp-bom", version.ref = "okhttpBom" } | okhttp-bom = { module = "com.squareup.okhttp3:okhttp-bom", version.ref = "okhttpBom" } | ||||||
| slf4j-android = { module = "org.slf4j:slf4j-android", version.ref = "slf4jAndroid" } | slf4j-android = { module = "org.slf4j:slf4j-android", version.ref = "slf4jAndroid" } | ||||||
| timber = { module = "com.jakewharton.timber:timber", version.ref = "timber" } | timber = { module = "com.jakewharton.timber:timber", version.ref = "timber" } | ||||||
|  | hilt-android = { group = "com.google.dagger", name = "hilt-android", version.ref = "hilt" } | ||||||
| #Build plugins | hilt-compiler = { group = "com.google.dagger", name = "hilt-compiler", version.ref = "hilt" } | ||||||
| android-gradlePlugin = { group = "com.android.tools.build", name = "gradle", version.ref = "androidGradlePlugin" } |  | ||||||
| compose-gradlePlugin = { module = "org.jetbrains.kotlin:compose-compiler-gradle-plugin", version.ref = "kotlin" } |  | ||||||
| kotlin-gradlePlugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" } |  | ||||||
| ksp-gradlePlugin = { group = "com.google.devtools.ksp", name = "com.google.devtools.ksp.gradle.plugin", version.ref = "ksp" } |  | ||||||
|  |  | ||||||
| [plugins] | [plugins] | ||||||
| android-application = { id = "com.android.application", version.ref = "agp" } | android-application = { id = "com.android.application", version.ref = "agp" } | ||||||
| compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } | kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } | ||||||
|  | hilt = { id = "com.google.dagger.hilt.android", version.ref = "hilt" } | ||||||
| convention-android-application = { id = "convention.android.application", version = "unspecified" } | convention-android-application = { id = "convention.android.application", version = "unspecified" } | ||||||
| convention-android-library = { id = "convention.android.library", version = "unspecified" } | convention-android-library = { id = "convention.android.library", version = "unspecified" } | ||||||
| convention-compose = { id = "convention.compose", version = "unspecified" } | convention-compose = { id = "convention.compose", version = "unspecified" } | ||||||
| hilt = { id = "com.google.dagger.hilt.android", version.ref = "hilt" } |  | ||||||
| kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } |  | ||||||
| kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlinSerialization" } |  | ||||||
| ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } | ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } | ||||||
|  | kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlinSerialization" } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user