diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 7b1990b6..fc47faa6 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -5,6 +5,7 @@ plugins { id("org.jetbrains.kotlin.android") id("kotlin-kapt") id("androidx.navigation.safeargs") + id("com.google.dagger.hilt.android") } android { @@ -30,7 +31,11 @@ android { } buildConfigField("String", "PUBLIC_KEY", localProperties.getProperty("publicKey") ?: "\"\"") - buildConfigField("String", "PRIVATE_KEY", localProperties.getProperty("privateKey") ?: "\"\"") + buildConfigField( + "String", + "PRIVATE_KEY", + localProperties.getProperty("privateKey") ?: "\"\"" + ) } buildTypes { @@ -49,7 +54,7 @@ android { kotlinOptions { jvmTarget = "17" } - dataBinding{ + dataBinding { enable = true } viewBinding { @@ -58,6 +63,9 @@ android { buildFeatures { buildConfig = true } + kapt { + correctErrorTypes = true + } } dependencies { @@ -80,6 +88,7 @@ dependencies { // LiveData implementation("androidx.lifecycle:lifecycle-livedata-ktx:$lifecycleVersion") + implementation("androidx.lifecycle:lifecycle-reactivestreams-ktx:$lifecycleVersion") // Retrofit implementation("com.squareup.retrofit2:retrofit:2.9.0") @@ -105,10 +114,22 @@ dependencies { implementation("com.github.bumptech.glide:glide:4.15.1") //navigation - val nav_version = "2.5.1" - implementation("androidx.navigation:navigation-fragment-ktx:$nav_version") - implementation("androidx.navigation:navigation-ui-ktx:$nav_version") + val navVersion = "2.5.1" + implementation("androidx.navigation:navigation-fragment-ktx:$navVersion") + implementation("androidx.navigation:navigation-ui-ktx:$navVersion") // Lottie Animation implementation("com.airbnb.android:lottie:6.0.0") + + // Room Database + val roomVersion = "2.5.1" + implementation("androidx.room:room-runtime:$roomVersion") + kapt("androidx.room:room-compiler:$roomVersion") + implementation("androidx.room:room-ktx:$roomVersion") + implementation("androidx.room:room-rxjava3:$roomVersion") + + // Dagger Hilt + val hiltVersion = "2.44" + implementation("com.google.dagger:hilt-android:$hiltVersion") + kapt("com.google.dagger:hilt-android-compiler:$hiltVersion") } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 66965fc1..7e252004 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -5,8 +5,8 @@ + android:usesCleartextTraffic="true" + tools:targetApi="31"> + android:theme="@style/Theme.Marvel"> diff --git a/app/src/main/java/com/red_velvet/marvel/MarvelApplication.kt b/app/src/main/java/com/red_velvet/marvel/MarvelApplication.kt new file mode 100644 index 00000000..c0b05c77 --- /dev/null +++ b/app/src/main/java/com/red_velvet/marvel/MarvelApplication.kt @@ -0,0 +1,7 @@ +package com.red_velvet.marvel + +import android.app.Application +import dagger.hilt.android.HiltAndroidApp + +@HiltAndroidApp +class MarvelApplication : Application() \ No newline at end of file diff --git a/app/src/main/java/com/red_velvet/marvel/data/local/database/MarvelDatabase.kt b/app/src/main/java/com/red_velvet/marvel/data/local/database/MarvelDatabase.kt new file mode 100644 index 00000000..834811d6 --- /dev/null +++ b/app/src/main/java/com/red_velvet/marvel/data/local/database/MarvelDatabase.kt @@ -0,0 +1,20 @@ +package com.red_velvet.marvel.data.local.database + +import androidx.room.Database +import androidx.room.RoomDatabase +import com.red_velvet.marvel.data.local.database.dao.CharacterDao +import com.red_velvet.marvel.data.local.database.dao.ComicDao +import com.red_velvet.marvel.data.local.database.dao.EventDao +import com.red_velvet.marvel.data.local.database.entity.CharacterEntity +import com.red_velvet.marvel.data.local.database.entity.ComicEntity +import com.red_velvet.marvel.data.local.database.entity.EventEntity + +@Database( + entities = [ComicEntity::class, EventEntity::class, CharacterEntity::class], + version = 1, +) +abstract class MarvelDatabase : RoomDatabase() { + abstract fun comicDao(): ComicDao + abstract fun eventDao(): EventDao + abstract fun characterDao(): CharacterDao +} \ No newline at end of file diff --git a/app/src/main/java/com/red_velvet/marvel/data/local/database/dao/CharacterDao.kt b/app/src/main/java/com/red_velvet/marvel/data/local/database/dao/CharacterDao.kt new file mode 100644 index 00000000..c717ce5e --- /dev/null +++ b/app/src/main/java/com/red_velvet/marvel/data/local/database/dao/CharacterDao.kt @@ -0,0 +1,21 @@ +package com.red_velvet.marvel.data.local.database.dao + +import androidx.room.Dao +import androidx.room.Insert +import androidx.room.OnConflictStrategy +import androidx.room.Query +import com.red_velvet.marvel.data.local.database.entity.CharacterEntity +import io.reactivex.rxjava3.core.Observable + +@Dao +interface CharacterDao { + + @Insert(onConflict = OnConflictStrategy.REPLACE) + fun insert(character: CharacterEntity) + + @Insert(onConflict = OnConflictStrategy.REPLACE) + fun insertAll(characters: List) + + @Query("SELECT * FROM CHARACTER_TABLE") + fun getAll(): Observable> +} \ No newline at end of file diff --git a/app/src/main/java/com/red_velvet/marvel/data/local/database/dao/ComicDao.kt b/app/src/main/java/com/red_velvet/marvel/data/local/database/dao/ComicDao.kt new file mode 100644 index 00000000..203bed05 --- /dev/null +++ b/app/src/main/java/com/red_velvet/marvel/data/local/database/dao/ComicDao.kt @@ -0,0 +1,27 @@ +package com.red_velvet.marvel.data.local.database.dao + +import androidx.room.Dao +import androidx.room.Delete +import androidx.room.Insert +import androidx.room.OnConflictStrategy +import androidx.room.Query +import com.red_velvet.marvel.data.local.database.entity.ComicEntity +import io.reactivex.rxjava3.core.Completable +import io.reactivex.rxjava3.core.Observable + +@Dao +interface ComicDao { + + @Insert(onConflict = OnConflictStrategy.REPLACE) + fun insert(comic: ComicEntity) + + @Insert(onConflict = OnConflictStrategy.REPLACE) + fun insertAll(comics: List) + + @Query("SELECT * FROM COMIC_TABLE") + fun getAll(): Observable> + + @Delete + fun delete(comic: ComicEntity): Completable + +} \ No newline at end of file diff --git a/app/src/main/java/com/red_velvet/marvel/data/local/database/dao/EventDao.kt b/app/src/main/java/com/red_velvet/marvel/data/local/database/dao/EventDao.kt new file mode 100644 index 00000000..846b2bb5 --- /dev/null +++ b/app/src/main/java/com/red_velvet/marvel/data/local/database/dao/EventDao.kt @@ -0,0 +1,20 @@ +package com.red_velvet.marvel.data.local.database.dao + +import androidx.room.Dao +import androidx.room.Insert +import androidx.room.OnConflictStrategy +import androidx.room.Query +import com.red_velvet.marvel.data.local.database.entity.EventEntity +import io.reactivex.rxjava3.core.Observable + +@Dao +interface EventDao { + @Insert(onConflict = OnConflictStrategy.REPLACE) + fun insert(event: EventEntity) + + @Insert(onConflict = OnConflictStrategy.REPLACE) + fun insertAll(events: List) + + @Query("SELECT * FROM EVENT_TABLE") + fun getAll(): Observable> +} \ No newline at end of file diff --git a/app/src/main/java/com/red_velvet/marvel/data/local/database/entity/CharacterEntity.kt b/app/src/main/java/com/red_velvet/marvel/data/local/database/entity/CharacterEntity.kt new file mode 100644 index 00000000..19b50929 --- /dev/null +++ b/app/src/main/java/com/red_velvet/marvel/data/local/database/entity/CharacterEntity.kt @@ -0,0 +1,11 @@ +package com.red_velvet.marvel.data.local.database.entity + +import androidx.room.Entity +import androidx.room.PrimaryKey + +@Entity(tableName = "CHARACTER_TABLE") +data class CharacterEntity( + @PrimaryKey val id: Int, + val name: String, + val imageUrl: String, +) diff --git a/app/src/main/java/com/red_velvet/marvel/data/local/database/entity/ComicEntity.kt b/app/src/main/java/com/red_velvet/marvel/data/local/database/entity/ComicEntity.kt new file mode 100644 index 00000000..b544f4cb --- /dev/null +++ b/app/src/main/java/com/red_velvet/marvel/data/local/database/entity/ComicEntity.kt @@ -0,0 +1,11 @@ +package com.red_velvet.marvel.data.local.database.entity + +import androidx.room.Entity +import androidx.room.PrimaryKey + +@Entity(tableName = "COMIC_TABLE") +data class ComicEntity( + @PrimaryKey val id: Int, + val title: String, + val imageUrl: String, +) \ No newline at end of file diff --git a/app/src/main/java/com/red_velvet/marvel/data/local/database/entity/EventEntity.kt b/app/src/main/java/com/red_velvet/marvel/data/local/database/entity/EventEntity.kt new file mode 100644 index 00000000..e876d7ec --- /dev/null +++ b/app/src/main/java/com/red_velvet/marvel/data/local/database/entity/EventEntity.kt @@ -0,0 +1,11 @@ +package com.red_velvet.marvel.data.local.database.entity + +import androidx.room.Entity +import androidx.room.PrimaryKey + +@Entity(tableName = "EVENT_TABLE") +data class EventEntity( + @PrimaryKey val id: Int, + val title: String, + val imageUrl: String, +) diff --git a/app/src/main/java/com/red_velvet/marvel/data/local/mapper/CharacterEntityMapper.kt b/app/src/main/java/com/red_velvet/marvel/data/local/mapper/CharacterEntityMapper.kt new file mode 100644 index 00000000..7165be13 --- /dev/null +++ b/app/src/main/java/com/red_velvet/marvel/data/local/mapper/CharacterEntityMapper.kt @@ -0,0 +1,16 @@ +package com.red_velvet.marvel.data.local.mapper + +import com.red_velvet.marvel.data.local.database.entity.CharacterEntity +import com.red_velvet.marvel.data.remote.dto.CharacterDto +import com.red_velvet.marvel.domain.mapper.Mapper +import com.red_velvet.marvel.domain.util.toUrl + +class CharacterEntityMapper : Mapper { + override fun map(input: CharacterDto): CharacterEntity { + return CharacterEntity( + id = input.id ?: 0, + name = input.name ?: "", + imageUrl = input.thumbnail?.toUrl() ?: "" + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/red_velvet/marvel/data/local/mapper/ComicEntityMapper.kt b/app/src/main/java/com/red_velvet/marvel/data/local/mapper/ComicEntityMapper.kt new file mode 100644 index 00000000..3223e454 --- /dev/null +++ b/app/src/main/java/com/red_velvet/marvel/data/local/mapper/ComicEntityMapper.kt @@ -0,0 +1,16 @@ +package com.red_velvet.marvel.data.local.mapper + +import com.red_velvet.marvel.data.local.database.entity.ComicEntity +import com.red_velvet.marvel.data.remote.dto.ComicDto +import com.red_velvet.marvel.domain.mapper.Mapper +import com.red_velvet.marvel.domain.util.toUrl + +class ComicEntityMapper : Mapper { + override fun map(input: ComicDto): ComicEntity { + return ComicEntity( + id = input.id ?: 0, + title = input.title ?: "", + imageUrl = input.thumbnail?.toUrl() ?: "", + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/red_velvet/marvel/data/local/mapper/EventEntityMapper.kt b/app/src/main/java/com/red_velvet/marvel/data/local/mapper/EventEntityMapper.kt new file mode 100644 index 00000000..736de860 --- /dev/null +++ b/app/src/main/java/com/red_velvet/marvel/data/local/mapper/EventEntityMapper.kt @@ -0,0 +1,16 @@ +package com.red_velvet.marvel.data.local.mapper + +import com.red_velvet.marvel.data.local.database.entity.EventEntity +import com.red_velvet.marvel.data.remote.dto.EventDto +import com.red_velvet.marvel.domain.mapper.Mapper +import com.red_velvet.marvel.domain.util.toUrl + +class EventEntityMapper : Mapper { + override fun map(input: EventDto): EventEntity { + return EventEntity( + id = input.id ?: 0, + title = input.title ?: "", + imageUrl = input.thumbnail?.toUrl() ?: "", + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/red_velvet/marvel/data/remote/RetrofitClient.kt b/app/src/main/java/com/red_velvet/marvel/data/remote/RetrofitClient.kt deleted file mode 100644 index dc1dc469..00000000 --- a/app/src/main/java/com/red_velvet/marvel/data/remote/RetrofitClient.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.red_velvet.marvel.data.remote - -import okhttp3.OkHttpClient -import retrofit2.Retrofit -import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory -import retrofit2.converter.gson.GsonConverterFactory - -object RetrofitClient { - - private val client = - OkHttpClient().newBuilder().addInterceptor(AuthorizationInterceptor()).build() - - private const val BASE_URL = "http://gateway.marvel.com/v1/public/" - - private val retrofit = Retrofit.Builder() - .baseUrl(BASE_URL) - .client(client) - .addConverterFactory(GsonConverterFactory.create()) - .addCallAdapterFactory(RxJava3CallAdapterFactory.create()) - .build() - - val apiService: MarvelService = retrofit.create(MarvelService::class.java) - -} \ No newline at end of file diff --git a/app/src/main/java/com/red_velvet/marvel/data/model/BaseResponse.kt b/app/src/main/java/com/red_velvet/marvel/data/remote/dto/BaseResponse.kt similarity index 84% rename from app/src/main/java/com/red_velvet/marvel/data/model/BaseResponse.kt rename to app/src/main/java/com/red_velvet/marvel/data/remote/dto/BaseResponse.kt index d6a13bd4..28dfcb0f 100644 --- a/app/src/main/java/com/red_velvet/marvel/data/model/BaseResponse.kt +++ b/app/src/main/java/com/red_velvet/marvel/data/remote/dto/BaseResponse.kt @@ -1,4 +1,4 @@ -package com.red_velvet.marvel.data.model +package com.red_velvet.marvel.data.remote.dto import com.google.gson.annotations.SerializedName @@ -13,7 +13,7 @@ data class BaseResponse( @SerializedName("copyright") val copyright: String? = "", @SerializedName("data") - val body: DataContainer? = null, + val body: DataContainerDto? = null, @SerializedName("etag") val etag: String? = "", @SerializedName("status") diff --git a/app/src/main/java/com/red_velvet/marvel/data/model/Character.kt b/app/src/main/java/com/red_velvet/marvel/data/remote/dto/CharacterDto.kt similarity index 53% rename from app/src/main/java/com/red_velvet/marvel/data/model/Character.kt rename to app/src/main/java/com/red_velvet/marvel/data/remote/dto/CharacterDto.kt index 5f521352..5bb4f01d 100644 --- a/app/src/main/java/com/red_velvet/marvel/data/model/Character.kt +++ b/app/src/main/java/com/red_velvet/marvel/data/remote/dto/CharacterDto.kt @@ -1,15 +1,15 @@ -package com.red_velvet.marvel.data.model +package com.red_velvet.marvel.data.remote.dto import com.google.gson.annotations.SerializedName -import com.red_velvet.marvel.data.model.* +import com.red_velvet.marvel.data.remote.dto.* -data class Character( +data class CharacterDto( @SerializedName("comics") - val comics: ResourceCollection? = ResourceCollection(), + val comics: ResourceCollectionDto? = ResourceCollectionDto(), @SerializedName("description") val description: String?, @SerializedName("events") - val events: ResourceCollection? = ResourceCollection(), + val events: ResourceCollectionDto? = ResourceCollectionDto(), @SerializedName("id") val id: Int?, @SerializedName("modified") @@ -19,11 +19,11 @@ data class Character( @SerializedName("resourceURI") val resourceURI: String?, @SerializedName("series") - val series: ResourceCollection? = ResourceCollection(), + val series: ResourceCollectionDto? = ResourceCollectionDto(), @SerializedName("stories") - val stories: ResourceCollection? = ResourceCollection(), + val stories: ResourceCollectionDto? = ResourceCollectionDto(), @SerializedName("thumbnail") - val thumbnail: Thumbnail?, + val thumbnail: ThumbnailDto?, @SerializedName("urls") - val urls: List + val urls: List ) \ No newline at end of file diff --git a/app/src/main/java/com/red_velvet/marvel/data/model/Comic.kt b/app/src/main/java/com/red_velvet/marvel/data/remote/dto/ComicDto.kt similarity index 62% rename from app/src/main/java/com/red_velvet/marvel/data/model/Comic.kt rename to app/src/main/java/com/red_velvet/marvel/data/remote/dto/ComicDto.kt index 64f78ac3..4852b383 100644 --- a/app/src/main/java/com/red_velvet/marvel/data/model/Comic.kt +++ b/app/src/main/java/com/red_velvet/marvel/data/remote/dto/ComicDto.kt @@ -1,19 +1,19 @@ -package com.red_velvet.marvel.data.model +package com.red_velvet.marvel.data.remote.dto import com.google.gson.annotations.SerializedName -data class Comic( +data class ComicDto( @SerializedName("characters") - val characters: ResourceCollection? = ResourceCollection(), + val characters: ResourceCollectionDto? = ResourceCollectionDto(), @SerializedName("collectedIssues") - val collectedIssues: List? = listOf(), + val collectedIssues: List? = listOf(), @SerializedName("collections") - val collections: List? = listOf(), + val collections: List? = listOf(), @SerializedName("creators") - val creators: ResourceCollection? = ResourceCollection(), + val creators: ResourceCollectionDto? = ResourceCollectionDto(), @SerializedName("dates") - val dates: List? = listOf(), + val dates: List? = listOf(), @SerializedName("description") val description: String? = "", @SerializedName("diamondCode") @@ -23,13 +23,13 @@ data class Comic( @SerializedName("ean") val ean: String? = "", @SerializedName("events") - val events: ResourceCollection? = ResourceCollection(), + val events: ResourceCollectionDto? = ResourceCollectionDto(), @SerializedName("format") val format: String? = "", @SerializedName("id") val id: Int? = 0, @SerializedName("images") - val images: List? = listOf(), + val images: List? = listOf(), @SerializedName("isbn") val isbn: String? = "", @SerializedName("issn") @@ -41,25 +41,25 @@ data class Comic( @SerializedName("pageCount") val pageCount: Int? = 0, @SerializedName("prices") - val prices: List? = listOf(), + val prices: List? = listOf(), @SerializedName("resourceURI") val resourceURI: String? = "", @SerializedName("series") - val series: ResourceCollection? = ResourceCollection(), + val series: ResourceCollectionDto? = ResourceCollectionDto(), @SerializedName("stories") - val stories: ResourceCollection? = ResourceCollection(), + val stories: ResourceCollectionDto? = ResourceCollectionDto(), @SerializedName("textObjects") - val textBlurbs: List? = listOf(), + val textBlurbs: List? = listOf(), @SerializedName("thumbnail") - val thumbnail: Thumbnail? = Thumbnail(), + val thumbnail: ThumbnailDto? = ThumbnailDto(), @SerializedName("title") val title: String? = "", @SerializedName("upc") val upc: String? = "", @SerializedName("urls") - val urls: List? = listOf(), + val urls: List? = listOf(), @SerializedName("variantDescription") val variantDescription: String? = "", @SerializedName("variants") - val variants: List? = listOf() + val variants: List? = listOf() ) \ No newline at end of file diff --git a/app/src/main/java/com/red_velvet/marvel/data/model/Creator.kt b/app/src/main/java/com/red_velvet/marvel/data/remote/dto/CreatorDto.kt similarity index 64% rename from app/src/main/java/com/red_velvet/marvel/data/model/Creator.kt rename to app/src/main/java/com/red_velvet/marvel/data/remote/dto/CreatorDto.kt index 4a5c8e90..5344b59d 100644 --- a/app/src/main/java/com/red_velvet/marvel/data/model/Creator.kt +++ b/app/src/main/java/com/red_velvet/marvel/data/remote/dto/CreatorDto.kt @@ -1,8 +1,8 @@ -package com.red_velvet.marvel.data.model +package com.red_velvet.marvel.data.remote.dto import com.google.gson.annotations.SerializedName -data class Creator( +data class CreatorDto( @SerializedName("id") val id: Int? = null, @SerializedName("firstName") @@ -18,17 +18,17 @@ data class Creator( @SerializedName("modified") val modified: String? = null, @SerializedName("thumbnail") - val thumbnail: Thumbnail? = Thumbnail(), + val thumbnail: ThumbnailDto? = ThumbnailDto(), @SerializedName("resourceURI") val resourceURI: String? = null, @SerializedName("comics") - val comics: ResourceCollection? = ResourceCollection(), + val comics: ResourceCollectionDto? = ResourceCollectionDto(), @SerializedName("series") - val series: ResourceCollection? = ResourceCollection(), + val series: ResourceCollectionDto? = ResourceCollectionDto(), @SerializedName("stories") - val stories: ResourceCollection? = ResourceCollection(), + val stories: ResourceCollectionDto? = ResourceCollectionDto(), @SerializedName("events") - val events: ResourceCollection? = ResourceCollection(), + val events: ResourceCollectionDto? = ResourceCollectionDto(), @SerializedName("urls") - val urls: List = listOf() + val urls: List = listOf() ) \ No newline at end of file diff --git a/app/src/main/java/com/red_velvet/marvel/data/model/DataContainer.kt b/app/src/main/java/com/red_velvet/marvel/data/remote/dto/DataContainerDto.kt similarity index 80% rename from app/src/main/java/com/red_velvet/marvel/data/model/DataContainer.kt rename to app/src/main/java/com/red_velvet/marvel/data/remote/dto/DataContainerDto.kt index 892c8181..96c8f1a7 100644 --- a/app/src/main/java/com/red_velvet/marvel/data/model/DataContainer.kt +++ b/app/src/main/java/com/red_velvet/marvel/data/remote/dto/DataContainerDto.kt @@ -1,9 +1,9 @@ -package com.red_velvet.marvel.data.model +package com.red_velvet.marvel.data.remote.dto import com.google.gson.annotations.SerializedName -data class DataContainer( +data class DataContainerDto( @SerializedName("count") val count: Int? = 0, @SerializedName("limit") diff --git a/app/src/main/java/com/red_velvet/marvel/data/model/Date.kt b/app/src/main/java/com/red_velvet/marvel/data/remote/dto/DateDto.kt similarity index 71% rename from app/src/main/java/com/red_velvet/marvel/data/model/Date.kt rename to app/src/main/java/com/red_velvet/marvel/data/remote/dto/DateDto.kt index 4bc86fc9..1974d39e 100644 --- a/app/src/main/java/com/red_velvet/marvel/data/model/Date.kt +++ b/app/src/main/java/com/red_velvet/marvel/data/remote/dto/DateDto.kt @@ -1,9 +1,9 @@ -package com.red_velvet.marvel.data.model +package com.red_velvet.marvel.data.remote.dto import com.google.gson.annotations.SerializedName -data class Date( +data class DateDto( @SerializedName("date") val date: String? = null, @SerializedName("type") diff --git a/app/src/main/java/com/red_velvet/marvel/data/model/Event.kt b/app/src/main/java/com/red_velvet/marvel/data/remote/dto/EventDto.kt similarity index 58% rename from app/src/main/java/com/red_velvet/marvel/data/model/Event.kt rename to app/src/main/java/com/red_velvet/marvel/data/remote/dto/EventDto.kt index fb4b08a9..b927df42 100644 --- a/app/src/main/java/com/red_velvet/marvel/data/model/Event.kt +++ b/app/src/main/java/com/red_velvet/marvel/data/remote/dto/EventDto.kt @@ -1,9 +1,9 @@ -package com.red_velvet.marvel.data.model +package com.red_velvet.marvel.data.remote.dto import com.google.gson.annotations.SerializedName -data class Event( +data class EventDto( @SerializedName("id") val id: Int? = 0, @SerializedName("title") @@ -13,7 +13,7 @@ data class Event( @SerializedName("resourceURI") val resourceURI: String? = "", @SerializedName("urls") - val urls: List? = listOf(), + val urls: List? = listOf(), @SerializedName("modified") val modified: String? = "", @SerializedName("start") @@ -21,15 +21,15 @@ data class Event( @SerializedName("end") val end: String? = "", @SerializedName("thumbnail") - val thumbnail: Thumbnail? = Thumbnail(), + val thumbnail: ThumbnailDto? = ThumbnailDto(), @SerializedName("creators") - val creators: ResourceCollection? = ResourceCollection(), + val creators: ResourceCollectionDto? = ResourceCollectionDto(), @SerializedName("characters") - val characters: ResourceCollection? = ResourceCollection(), + val characters: ResourceCollectionDto? = ResourceCollectionDto(), @SerializedName("stories") - val stories: ResourceCollection? = ResourceCollection(), + val stories: ResourceCollectionDto? = ResourceCollectionDto(), @SerializedName("comics") - val comics: ResourceCollection? = ResourceCollection(), + val comics: ResourceCollectionDto? = ResourceCollectionDto(), @SerializedName("series") - val series: ResourceCollection? = ResourceCollection(), + val series: ResourceCollectionDto? = ResourceCollectionDto(), ) \ No newline at end of file diff --git a/app/src/main/java/com/red_velvet/marvel/data/model/Price.kt b/app/src/main/java/com/red_velvet/marvel/data/remote/dto/PriceDto.kt similarity index 71% rename from app/src/main/java/com/red_velvet/marvel/data/model/Price.kt rename to app/src/main/java/com/red_velvet/marvel/data/remote/dto/PriceDto.kt index 5739bc3b..845a0f9a 100644 --- a/app/src/main/java/com/red_velvet/marvel/data/model/Price.kt +++ b/app/src/main/java/com/red_velvet/marvel/data/remote/dto/PriceDto.kt @@ -1,9 +1,9 @@ -package com.red_velvet.marvel.data.model +package com.red_velvet.marvel.data.remote.dto import com.google.gson.annotations.SerializedName -data class Price( +data class PriceDto( @SerializedName("price") val price: Double? = null, @SerializedName("type") diff --git a/app/src/main/java/com/red_velvet/marvel/data/model/ResourceCollection.kt b/app/src/main/java/com/red_velvet/marvel/data/remote/dto/ResourceCollectionDto.kt similarity index 76% rename from app/src/main/java/com/red_velvet/marvel/data/model/ResourceCollection.kt rename to app/src/main/java/com/red_velvet/marvel/data/remote/dto/ResourceCollectionDto.kt index 93b8a596..e0ee55b3 100644 --- a/app/src/main/java/com/red_velvet/marvel/data/model/ResourceCollection.kt +++ b/app/src/main/java/com/red_velvet/marvel/data/remote/dto/ResourceCollectionDto.kt @@ -1,14 +1,14 @@ -package com.red_velvet.marvel.data.model +package com.red_velvet.marvel.data.remote.dto import com.google.gson.annotations.SerializedName -data class ResourceCollection( +data class ResourceCollectionDto( @SerializedName("available") val available: Int? = 0, @SerializedName("collectionURI") val collectionURI: String? = null, @SerializedName("items") - val items: List? = listOf(), + val items: List? = listOf(), @SerializedName("returned") val returned: Int? = 0, @SerializedName("name") diff --git a/app/src/main/java/com/red_velvet/marvel/data/model/Resource.kt b/app/src/main/java/com/red_velvet/marvel/data/remote/dto/ResourceDto.kt similarity index 81% rename from app/src/main/java/com/red_velvet/marvel/data/model/Resource.kt rename to app/src/main/java/com/red_velvet/marvel/data/remote/dto/ResourceDto.kt index 495aafdb..6ad58a3d 100644 --- a/app/src/main/java/com/red_velvet/marvel/data/model/Resource.kt +++ b/app/src/main/java/com/red_velvet/marvel/data/remote/dto/ResourceDto.kt @@ -1,9 +1,9 @@ -package com.red_velvet.marvel.data.model +package com.red_velvet.marvel.data.remote.dto import com.google.gson.annotations.SerializedName -data class Resource( +data class ResourceDto( @SerializedName("name") val name: String? = null, @SerializedName("resourceURI") diff --git a/app/src/main/java/com/red_velvet/marvel/data/model/Series.kt b/app/src/main/java/com/red_velvet/marvel/data/remote/dto/SeriesDto.kt similarity index 67% rename from app/src/main/java/com/red_velvet/marvel/data/model/Series.kt rename to app/src/main/java/com/red_velvet/marvel/data/remote/dto/SeriesDto.kt index 64006d2d..bb20d54f 100644 --- a/app/src/main/java/com/red_velvet/marvel/data/model/Series.kt +++ b/app/src/main/java/com/red_velvet/marvel/data/remote/dto/SeriesDto.kt @@ -1,29 +1,29 @@ -package com.red_velvet.marvel.data.model +package com.red_velvet.marvel.data.remote.dto import com.google.gson.annotations.SerializedName -data class Series( +data class SeriesDto( @SerializedName("characters") - val characters: ResourceCollection?, + val characters: ResourceCollectionDto?, @SerializedName("comics") - val comics: ResourceCollection?, + val comics: ResourceCollectionDto?, @SerializedName("creators") - val creators: ResourceCollection?, + val creators: ResourceCollectionDto?, @SerializedName("description") val description: String?, @SerializedName("endYear") val endYear: Int?, @SerializedName("events") - val events: ResourceCollection?, + val events: ResourceCollectionDto?, @SerializedName("id") val id: Int?, @SerializedName("modified") val modified: String?, @SerializedName("next") - val next: Resource?, + val next: ResourceDto?, @SerializedName("previous") - val previous: Resource?, + val previous: ResourceDto?, @SerializedName("rating") val rating: String?, @SerializedName("resourceURI") @@ -31,13 +31,13 @@ data class Series( @SerializedName("startYear") val startYear: Int?, @SerializedName("stories") - val stories: ResourceCollection?, + val stories: ResourceCollectionDto?, @SerializedName("thumbnail") - val thumbnail: Thumbnail?, + val thumbnail: ThumbnailDto?, @SerializedName("title") val title: String?, @SerializedName("type") val type: String?, @SerializedName("urls") - val urls: List? + val urls: List? ) \ No newline at end of file diff --git a/app/src/main/java/com/red_velvet/marvel/data/model/Story.kt b/app/src/main/java/com/red_velvet/marvel/data/remote/dto/StoryDto.kt similarity index 56% rename from app/src/main/java/com/red_velvet/marvel/data/model/Story.kt rename to app/src/main/java/com/red_velvet/marvel/data/remote/dto/StoryDto.kt index 96ea2ceb..f603e3df 100644 --- a/app/src/main/java/com/red_velvet/marvel/data/model/Story.kt +++ b/app/src/main/java/com/red_velvet/marvel/data/remote/dto/StoryDto.kt @@ -1,30 +1,30 @@ -package com.red_velvet.marvel.data.model +package com.red_velvet.marvel.data.remote.dto import com.google.gson.annotations.SerializedName -data class Story( +data class StoryDto( @SerializedName("characters") - val characters: ResourceCollection? = ResourceCollection(), + val characters: ResourceCollectionDto? = ResourceCollectionDto(), @SerializedName("comics") - val comics: ResourceCollection? = ResourceCollection(), + val comics: ResourceCollectionDto? = ResourceCollectionDto(), @SerializedName("creators") - val creators: ResourceCollection? = ResourceCollection(), + val creators: ResourceCollectionDto? = ResourceCollectionDto(), @SerializedName("description") val description: String, @SerializedName("events") - val events: ResourceCollection? = ResourceCollection(), + val events: ResourceCollectionDto? = ResourceCollectionDto(), @SerializedName("id") val id: Int? = null, @SerializedName("modified") val modified: String? = null, @SerializedName("originalIssue") - val originalIssue: Resource? = Resource(), + val originalIssue: ResourceDto? = ResourceDto(), @SerializedName("resourceURI") val resourceURI: String? = null, @SerializedName("series") - val series: ResourceCollection? = ResourceCollection(), + val series: ResourceCollectionDto? = ResourceCollectionDto(), @SerializedName("thumbnail") - val thumbnail: Thumbnail? = Thumbnail(), + val thumbnail: ThumbnailDto? = ThumbnailDto(), @SerializedName("title") val title: String? = null, @SerializedName("type") diff --git a/app/src/main/java/com/red_velvet/marvel/data/model/TextBlurb.kt b/app/src/main/java/com/red_velvet/marvel/data/remote/dto/TextBlurbDto.kt similarity index 76% rename from app/src/main/java/com/red_velvet/marvel/data/model/TextBlurb.kt rename to app/src/main/java/com/red_velvet/marvel/data/remote/dto/TextBlurbDto.kt index 557ad7bb..afd31d57 100644 --- a/app/src/main/java/com/red_velvet/marvel/data/model/TextBlurb.kt +++ b/app/src/main/java/com/red_velvet/marvel/data/remote/dto/TextBlurbDto.kt @@ -1,9 +1,9 @@ -package com.red_velvet.marvel.data.model +package com.red_velvet.marvel.data.remote.dto import com.google.gson.annotations.SerializedName -data class TextBlurb( +data class TextBlurbDto( @SerializedName("language") val language: String? = null, @SerializedName("text") diff --git a/app/src/main/java/com/red_velvet/marvel/data/model/Thumbnail.kt b/app/src/main/java/com/red_velvet/marvel/data/remote/dto/ThumbnailDto.kt similarity index 71% rename from app/src/main/java/com/red_velvet/marvel/data/model/Thumbnail.kt rename to app/src/main/java/com/red_velvet/marvel/data/remote/dto/ThumbnailDto.kt index 266d222b..110d8c50 100644 --- a/app/src/main/java/com/red_velvet/marvel/data/model/Thumbnail.kt +++ b/app/src/main/java/com/red_velvet/marvel/data/remote/dto/ThumbnailDto.kt @@ -1,9 +1,9 @@ -package com.red_velvet.marvel.data.model +package com.red_velvet.marvel.data.remote.dto import com.google.gson.annotations.SerializedName -data class Thumbnail( +data class ThumbnailDto( @SerializedName("extension") val extension: String? = null, @SerializedName("path") diff --git a/app/src/main/java/com/red_velvet/marvel/data/model/Url.kt b/app/src/main/java/com/red_velvet/marvel/data/remote/dto/UrlDto.kt similarity index 71% rename from app/src/main/java/com/red_velvet/marvel/data/model/Url.kt rename to app/src/main/java/com/red_velvet/marvel/data/remote/dto/UrlDto.kt index 6f3cd27e..3dc3f13a 100644 --- a/app/src/main/java/com/red_velvet/marvel/data/model/Url.kt +++ b/app/src/main/java/com/red_velvet/marvel/data/remote/dto/UrlDto.kt @@ -1,9 +1,9 @@ -package com.red_velvet.marvel.data.model +package com.red_velvet.marvel.data.remote.dto import com.google.gson.annotations.SerializedName -data class Url( +data class UrlDto( @SerializedName("type") val type: String? = null, @SerializedName("url") diff --git a/app/src/main/java/com/red_velvet/marvel/data/remote/MarvelService.kt b/app/src/main/java/com/red_velvet/marvel/data/remote/service/MarvelService.kt similarity index 62% rename from app/src/main/java/com/red_velvet/marvel/data/remote/MarvelService.kt rename to app/src/main/java/com/red_velvet/marvel/data/remote/service/MarvelService.kt index b2d45876..41016245 100644 --- a/app/src/main/java/com/red_velvet/marvel/data/remote/MarvelService.kt +++ b/app/src/main/java/com/red_velvet/marvel/data/remote/service/MarvelService.kt @@ -1,12 +1,12 @@ -package com.red_velvet.marvel.data.remote - -import com.red_velvet.marvel.data.model.BaseResponse -import com.red_velvet.marvel.data.model.Character -import com.red_velvet.marvel.data.model.Comic -import com.red_velvet.marvel.data.model.Creator -import com.red_velvet.marvel.data.model.Event -import com.red_velvet.marvel.data.model.Series -import com.red_velvet.marvel.data.model.Story +package com.red_velvet.marvel.data.remote.service + +import com.red_velvet.marvel.data.remote.dto.BaseResponse +import com.red_velvet.marvel.data.remote.dto.CharacterDto +import com.red_velvet.marvel.data.remote.dto.ComicDto +import com.red_velvet.marvel.data.remote.dto.CreatorDto +import com.red_velvet.marvel.data.remote.dto.EventDto +import com.red_velvet.marvel.data.remote.dto.SeriesDto +import com.red_velvet.marvel.data.remote.dto.StoryDto import io.reactivex.rxjava3.core.Single import retrofit2.Response import retrofit2.http.GET @@ -19,96 +19,96 @@ interface MarvelService { fun getAllComics( @Query("titleStartsWith") titleStartsWith: String? = null, @Query("dateDescriptor") dateDescriptor: String? = null, - ): Single>>> + ): Single>>> @GET("comics/{comicId}") fun getComicDetailById( @Path("comicId") comicId: Int - ): Single>>> + ): Single>>> @GET("characters/{characterId}/comics") fun getComicsByCharacterId( @Path("characterId") characterId: Int, @Query("titleStartsWith") titleStartsWith: String? = null, @Query("dateDescriptor") dateDescriptor: String? = null - ): Single>>> + ): Single>>> @GET("comics/{comicId}/creators") fun getCreatorByComicId( @Path("comicId") comicId: Int? = null, - ): Single>>> + ): Single>>> @GET("series") fun getAllSeries( @Query("titleStartsWith") titleStartsWith: String? = null, @Query("contains") contains: String? = null - ): Single>>> + ): Single>>> @GET("series/{seriesId}") fun getSeriesById( @Path("seriesId") seriesId: Int - ): Single>>> + ): Single>>> @GET("events") fun getAllEvents( @Query("nameStartsWith") nameStartsWith: String? = null - ): Single>>> + ): Single>>> @GET("comics/{comicId}/characters") fun getCharactersByComicId( @Path("comicId") comicId: Int? = null, - ): Single>>> + ): Single>>> @GET("events/{eventId}/characters") fun getCharactersByEventId( @Path("eventId") eventId: Int, - ): Single>>> + ): Single>>> @GET("events/{eventId}/creators") fun getCreatorsByEventId( @Path("eventId") eventId: Int - ): Single>>> + ): Single>>> @GET("stories") - fun getAllStories(): Single>>> + fun getAllStories(): Single>>> @GET("stories/{storyId}") fun getStoryById( @Path("storyId") storyId: Int - ): Single>>> + ): Single>>> @GET("stories/{storyId}/creators") fun getCreatorsByStoryId( @Path("storyId") storyId: Int - ): Single>>> + ): Single>>> @GET("stories/{storyId}/comics") fun getComicsByStoryId( @Path("storyId") storyId: Int - ): Single>>> + ): Single>>> @GET("characters") fun getAllCharacters( @Query("nameStartsWith") nameStartsWith: String? = null - ): Single>>> + ): Single>>> @GET("characters/{characterId}") fun getCharacterById( @Path("characterId") characterId: Int - ): Single>>> + ): Single>>> @GET("characters/{characterId}/series") fun getSeriesByCharacterId( @Path("characterId") characterId: Int - ): Single>>> + ): Single>>> @GET("series/{seriesId}/creators") fun getCreatorsBySeriesId( @Path("seriesId") seriesId: Int - ): Single>>> + ): Single>>> @GET("events/{eventId}") fun getEventById( @Path("eventId") eventId: Int - ): Single>>> + ): Single>>> } \ No newline at end of file diff --git a/app/src/main/java/com/red_velvet/marvel/data/repository/MarvelRepository.kt b/app/src/main/java/com/red_velvet/marvel/data/repository/MarvelRepository.kt index 247f0d0b..b42150e6 100644 --- a/app/src/main/java/com/red_velvet/marvel/data/repository/MarvelRepository.kt +++ b/app/src/main/java/com/red_velvet/marvel/data/repository/MarvelRepository.kt @@ -1,13 +1,17 @@ package com.red_velvet.marvel.data.repository -import com.red_velvet.marvel.data.model.Character -import com.red_velvet.marvel.data.model.Comic -import com.red_velvet.marvel.data.model.Creator -import com.red_velvet.marvel.data.model.Event -import com.red_velvet.marvel.data.model.Series -import com.red_velvet.marvel.data.model.Story +import com.red_velvet.marvel.data.remote.dto.CharacterDto +import com.red_velvet.marvel.data.remote.dto.ComicDto +import com.red_velvet.marvel.data.remote.dto.CreatorDto +import com.red_velvet.marvel.data.remote.dto.EventDto +import com.red_velvet.marvel.data.remote.dto.SeriesDto +import com.red_velvet.marvel.data.remote.dto.StoryDto +import com.red_velvet.marvel.domain.model.Character +import com.red_velvet.marvel.domain.model.Comic +import com.red_velvet.marvel.domain.model.Event import com.red_velvet.marvel.ui.utils.State +import io.reactivex.rxjava3.core.Completable import io.reactivex.rxjava3.core.Observable interface MarvelRepository { @@ -15,45 +19,61 @@ interface MarvelRepository { fun getAllComics( titleStartsWith: String? = null, dateDescriptor: String? = null, - ): Observable>> + ): Observable>> - fun getComicById(comicId: Int): Observable>> + fun getComicById(comicId: Int): Observable>> - fun getComicsByCharacterId(characterId: Int): Observable>> + fun getComicsByCharacterId(characterId: Int): Observable>> fun getAllSeries( titleStartsWith: String? = null, contains: String? = null - ): Observable>> + ): Observable>> - fun getCreatorByComicId(comicId: Int): Observable>> + fun getCreatorByComicId(comicId: Int): Observable>> - fun getSeriesById(seriesId: Int): Observable>> + fun getSeriesById(seriesId: Int): Observable>> - fun getAllEvents(query: String? = null): Observable>> + fun getAllEvents(query: String? = null): Observable>> - fun getCharactersByEventId(eventId: Int): Observable>> + fun getCharactersByEventId(eventId: Int): Observable>> - fun getCreatorsByEventId(eventId: Int): Observable>> + fun getCreatorsByEventId(eventId: Int): Observable>> - fun getAllStories(): Observable>> + fun getAllStories(): Observable>> - fun getStoryById(storyId: Int): Observable>> + fun getStoryById(storyId: Int): Observable>> - fun getCreatorsByStoryId(storyId: Int): Observable>> + fun getCreatorsByStoryId(storyId: Int): Observable>> - fun getComicsByStoryId(storyId: Int): Observable>> + fun getComicsByStoryId(storyId: Int): Observable>> - fun getCharactersByComicId(comicId: Int): Observable>> + fun getCharactersByComicId(comicId: Int): Observable>> - fun getEventById(eventId: Int): Observable>> + fun getEventById(eventId: Int): Observable>> - fun getAllCharacters(nameStartsWith: String? = null): Observable>> + fun getAllCharacters(nameStartsWith: String? = null): Observable>> - fun getCharacterById(characterId: Int): Observable>> + fun getCharacterById(characterId: Int): Observable>> - fun getCreatorsBySeriesId(seriesId: Int): Observable>> + fun getCreatorsBySeriesId(seriesId: Int): Observable>> + + fun getSeriesByCharacterId(characterId: Int): Observable>> + + fun refreshComics(): Completable + + fun getLocalComics( + titleStartsWith: String? = null, + contains: String? = null + ): Observable> + + fun refreshEvents(): Completable + + fun getLocalEvents(query: String? = null): Observable> + + fun refreshCharacters(): Completable + + fun getLocalCharacters(nameStartsWith: String? = null): Observable> - fun getSeriesByCharacterId(characterId: Int): Observable>> } diff --git a/app/src/main/java/com/red_velvet/marvel/data/repository/MarvelRepositoryImpl.kt b/app/src/main/java/com/red_velvet/marvel/data/repository/MarvelRepositoryImpl.kt index 2ee67b24..69d47a3a 100644 --- a/app/src/main/java/com/red_velvet/marvel/data/repository/MarvelRepositoryImpl.kt +++ b/app/src/main/java/com/red_velvet/marvel/data/repository/MarvelRepositoryImpl.kt @@ -1,106 +1,127 @@ package com.red_velvet.marvel.data.repository -import com.red_velvet.marvel.data.model.BaseResponse -import com.red_velvet.marvel.data.model.Character -import com.red_velvet.marvel.data.model.Comic -import com.red_velvet.marvel.data.model.Creator -import com.red_velvet.marvel.data.model.Event -import com.red_velvet.marvel.data.model.Series -import com.red_velvet.marvel.data.model.Story -import com.red_velvet.marvel.data.remote.MarvelService +import com.red_velvet.marvel.data.local.database.MarvelDatabase +import com.red_velvet.marvel.data.local.mapper.CharacterEntityMapper +import com.red_velvet.marvel.data.local.mapper.ComicEntityMapper +import com.red_velvet.marvel.data.local.mapper.EventEntityMapper +import com.red_velvet.marvel.data.remote.dto.BaseResponse +import com.red_velvet.marvel.data.remote.dto.CharacterDto +import com.red_velvet.marvel.data.remote.dto.ComicDto +import com.red_velvet.marvel.data.remote.dto.CreatorDto +import com.red_velvet.marvel.data.remote.dto.EventDto +import com.red_velvet.marvel.data.remote.dto.SeriesDto +import com.red_velvet.marvel.data.remote.dto.StoryDto +import com.red_velvet.marvel.data.remote.service.MarvelService +import com.red_velvet.marvel.data.util.extractResults +import com.red_velvet.marvel.domain.mapper.LocalCharacterMapper +import com.red_velvet.marvel.domain.mapper.LocalComicMapper +import com.red_velvet.marvel.domain.mapper.LocalEventMapper +import com.red_velvet.marvel.domain.model.Character +import com.red_velvet.marvel.domain.model.Comic +import com.red_velvet.marvel.domain.model.Event import com.red_velvet.marvel.ui.utils.State +import io.reactivex.rxjava3.core.Completable import io.reactivex.rxjava3.core.Observable import io.reactivex.rxjava3.core.Single +import io.reactivex.rxjava3.schedulers.Schedulers import retrofit2.Response - -class MarvelRepositoryImpl( - private val marvelServiceImpl: MarvelService +import javax.inject.Inject + +class MarvelRepositoryImpl @Inject constructor( + private val marvelServiceImpl: MarvelService, + private val marvelDatabase: MarvelDatabase, + private val ComicEntityMapper: ComicEntityMapper, + private val localComicMapper: LocalComicMapper, + private val eventEntityMapper: EventEntityMapper, + private val localEventMapper: LocalEventMapper, + private val characterEntityMapper: CharacterEntityMapper, + private val localCharacterMapper: LocalCharacterMapper, ) : MarvelRepository { override fun getAllComics( titleStartsWith: String?, dateDescriptor: String? - ): Observable>> { + ): Observable>> { return wrapWithState { marvelServiceImpl.getAllComics(titleStartsWith, dateDescriptor) } } - override fun getComicById(comicId: Int): Observable>> { + override fun getComicById(comicId: Int): Observable>> { return wrapWithState { marvelServiceImpl.getComicDetailById(comicId) } } - override fun getComicsByCharacterId(characterId: Int): Observable>> { + override fun getComicsByCharacterId(characterId: Int): Observable>> { return wrapWithState { marvelServiceImpl.getComicsByCharacterId(characterId) } } override fun getAllSeries( titleStartsWith: String?, contains: String? - ): Observable>> { + ): Observable>> { return wrapWithState { marvelServiceImpl.getAllSeries(titleStartsWith, contains) } } - override fun getCharactersByComicId(comicId: Int): Observable>> { + override fun getCharactersByComicId(comicId: Int): Observable>> { return wrapWithState { marvelServiceImpl.getCharactersByComicId(comicId) } } - override fun getSeriesById(seriesId: Int): Observable>> { + override fun getSeriesById(seriesId: Int): Observable>> { return wrapWithState { marvelServiceImpl.getSeriesById(seriesId) } } - override fun getAllEvents(query: String?): Observable>> { + override fun getAllEvents(query: String?): Observable>> { return wrapWithState { marvelServiceImpl.getAllEvents(query) } } - override fun getCreatorByComicId(comicId: Int): Observable>> { + override fun getCreatorByComicId(comicId: Int): Observable>> { return wrapWithState { marvelServiceImpl.getCreatorByComicId(comicId) } } - override fun getCharactersByEventId(eventId: Int): Observable>> { + override fun getCharactersByEventId(eventId: Int): Observable>> { return wrapWithState { marvelServiceImpl.getCharactersByEventId(eventId) } } - override fun getAllCharacters(nameStartsWith: String?): Observable>> { + override fun getAllCharacters(nameStartsWith: String?): Observable>> { return wrapWithState { marvelServiceImpl.getAllCharacters(nameStartsWith) } } - override fun getCharacterById(characterId: Int): Observable>> { + override fun getCharacterById(characterId: Int): Observable>> { return wrapWithState { marvelServiceImpl.getCharacterById(characterId) } } - override fun getCreatorsByEventId(eventId: Int): Observable>> { + override fun getCreatorsByEventId(eventId: Int): Observable>> { return wrapWithState { marvelServiceImpl.getCreatorsByEventId(eventId) } } - override fun getAllStories(): Observable>> { + override fun getAllStories(): Observable>> { return wrapWithState { marvelServiceImpl.getAllStories() } } - override fun getStoryById(storyId: Int): Observable>> { + override fun getStoryById(storyId: Int): Observable>> { return wrapWithState { marvelServiceImpl.getStoryById(storyId) } } - override fun getCreatorsByStoryId(storyId: Int): Observable>> { + override fun getCreatorsByStoryId(storyId: Int): Observable>> { return wrapWithState { marvelServiceImpl.getCreatorsByStoryId(storyId) } } - override fun getComicsByStoryId(storyId: Int): Observable>> { + override fun getComicsByStoryId(storyId: Int): Observable>> { return wrapWithState { marvelServiceImpl.getComicsByStoryId(storyId) } } override fun getSeriesByCharacterId( characterId: Int - ): Observable>> { + ): Observable>> { return wrapWithState { marvelServiceImpl.getSeriesByCharacterId(characterId) } } override fun getEventById( eventId: Int - ): Observable>> { + ): Observable>> { return wrapWithState { marvelServiceImpl.getEventById(eventId) } } - override fun getCreatorsBySeriesId(seriesId: Int): Observable>> { + override fun getCreatorsBySeriesId(seriesId: Int): Observable>> { return wrapWithState { marvelServiceImpl.getCreatorsBySeriesId(seriesId) } } @@ -116,4 +137,67 @@ class MarvelRepositoryImpl( .onErrorReturn { State.Failed(it.message ?: "Unknown error") } .startWith(Observable.just(State.Loading)) } + + override fun getLocalComics( + titleStartsWith: String?, + contains: String? + ): Observable> { + return marvelDatabase.comicDao().getAll() + .map { comics -> comics.map { localComicMapper.map(it) } } + } + + override fun getLocalEvents(query: String?): Observable> { + return marvelDatabase.eventDao().getAll() + .map { events -> events.map { localEventMapper.map(it) } } + } + + override fun getLocalCharacters(nameStartsWith: String?): Observable> { + return marvelDatabase.characterDao().getAll() + .map { characters -> characters.map { localCharacterMapper.map(it) } } + } + + override fun refreshComics(): Completable { + return marvelServiceImpl.getAllComics() + .flatMapCompletable { responseWrapper -> + val comics = responseWrapper.extractResults() + val comicsEntities = comics?.map { ComicEntityMapper.map(it) } + comicsEntities?.let { + Completable.fromAction { marvelDatabase.comicDao().insertAll(it) } + .subscribeOn(Schedulers.io()) + } ?: Completable.complete() + } + .onErrorResumeNext { + Completable.complete() + } + } + + override fun refreshEvents(): Completable { + return marvelServiceImpl.getAllEvents() + .flatMapCompletable { responseWrapper -> + val events = responseWrapper.extractResults() + val eventsEntities = events?.map { eventEntityMapper.map(it) } + eventsEntities?.let { + Completable.fromAction { marvelDatabase.eventDao().insertAll(it) } + .subscribeOn(Schedulers.io()) + } ?: Completable.complete() + } + .onErrorResumeNext { + Completable.complete() + } + } + + override fun refreshCharacters(): Completable { + return marvelServiceImpl.getAllCharacters() + .flatMapCompletable { responseWrapper -> + val characters = responseWrapper.extractResults() + val charactersEntities = characters?.map { characterEntityMapper.map(it) } + charactersEntities?.let { + Completable.fromAction { marvelDatabase.characterDao().insertAll(it) } + .subscribeOn(Schedulers.io()) + } ?: Completable.complete() + } + .onErrorResumeNext { + Completable.complete() + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/red_velvet/marvel/data/util/Extension.kt b/app/src/main/java/com/red_velvet/marvel/data/util/Extension.kt new file mode 100644 index 00000000..53947288 --- /dev/null +++ b/app/src/main/java/com/red_velvet/marvel/data/util/Extension.kt @@ -0,0 +1,8 @@ +package com.red_velvet.marvel.data.util + +import com.red_velvet.marvel.data.remote.dto.BaseResponse +import retrofit2.Response + +fun Response>>.extractResults(): List? { + return this.body()?.body?.results +} \ No newline at end of file diff --git a/app/src/main/java/com/red_velvet/marvel/di/DatabaseModule.kt b/app/src/main/java/com/red_velvet/marvel/di/DatabaseModule.kt new file mode 100644 index 00000000..023c0d37 --- /dev/null +++ b/app/src/main/java/com/red_velvet/marvel/di/DatabaseModule.kt @@ -0,0 +1,38 @@ +package com.red_velvet.marvel.di + +import android.content.Context +import androidx.room.Room +import com.red_velvet.marvel.data.local.database.MarvelDatabase +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.android.qualifiers.ApplicationContext +import dagger.hilt.components.SingletonComponent +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +object DatabaseModule { + + @Singleton + @Provides + fun provideMarvelDatabase(@ApplicationContext context: Context): MarvelDatabase { + return Room.databaseBuilder( + context, + MarvelDatabase::class.java, + "MarvelDatabase" + ).build() + } + + @Singleton + @Provides + fun provideComicDao(marvelDatabase: MarvelDatabase) = marvelDatabase.comicDao() + + @Singleton + @Provides + fun provideCharacterDao(marvelDatabase: MarvelDatabase) = marvelDatabase.characterDao() + + @Singleton + @Provides + fun provideEventDao(marvelDatabase: MarvelDatabase) = marvelDatabase.eventDao() +} \ No newline at end of file diff --git a/app/src/main/java/com/red_velvet/marvel/di/NetworkModule.kt b/app/src/main/java/com/red_velvet/marvel/di/NetworkModule.kt new file mode 100644 index 00000000..6cf20ccb --- /dev/null +++ b/app/src/main/java/com/red_velvet/marvel/di/NetworkModule.kt @@ -0,0 +1,66 @@ +package com.red_velvet.marvel.di + +import com.red_velvet.marvel.data.remote.AuthorizationInterceptor +import com.red_velvet.marvel.data.remote.service.MarvelService +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import okhttp3.OkHttpClient +import retrofit2.Retrofit +import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory +import retrofit2.converter.gson.GsonConverterFactory +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +object NetworkModule { + private const val BASE_URL = "http://gateway.marvel.com/v1/public/" + + @Singleton + @Provides + fun provideMarvelService(retrofit: Retrofit): MarvelService { + return retrofit.create(MarvelService::class.java) + } + + @Singleton + @Provides + fun provideRetrofit( + client: OkHttpClient, + gsonConverterFactory: GsonConverterFactory, + rxJava3CallAdapterFactory: RxJava3CallAdapterFactory + ): Retrofit { + return Retrofit.Builder() + .baseUrl(BASE_URL) + .client(client) + .addConverterFactory(gsonConverterFactory) + .addCallAdapterFactory(rxJava3CallAdapterFactory) + .build() + } + + @Singleton + @Provides + fun provideOkHttpClient(authorizationInterceptor: AuthorizationInterceptor): OkHttpClient { + return OkHttpClient.Builder() + .addInterceptor(authorizationInterceptor) + .build() + } + + @Singleton + @Provides + fun provideGsonConverterFactory(): GsonConverterFactory { + return GsonConverterFactory.create() + } + + @Singleton + @Provides + fun provideRxJava3CallAdapterFactory(): RxJava3CallAdapterFactory { + return RxJava3CallAdapterFactory.create() + } + + @Singleton + @Provides + fun provideAuthorizationInterceptor(): AuthorizationInterceptor { + return AuthorizationInterceptor() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/red_velvet/marvel/di/RepositoryModule.kt b/app/src/main/java/com/red_velvet/marvel/di/RepositoryModule.kt new file mode 100644 index 00000000..3b285fb7 --- /dev/null +++ b/app/src/main/java/com/red_velvet/marvel/di/RepositoryModule.kt @@ -0,0 +1,82 @@ +package com.red_velvet.marvel.di + +import com.red_velvet.marvel.data.local.database.MarvelDatabase +import com.red_velvet.marvel.data.local.mapper.CharacterEntityMapper +import com.red_velvet.marvel.data.local.mapper.ComicEntityMapper +import com.red_velvet.marvel.data.local.mapper.EventEntityMapper +import com.red_velvet.marvel.data.remote.service.MarvelService +import com.red_velvet.marvel.data.repository.MarvelRepository +import com.red_velvet.marvel.data.repository.MarvelRepositoryImpl +import com.red_velvet.marvel.domain.mapper.LocalCharacterMapper +import com.red_velvet.marvel.domain.mapper.LocalComicMapper +import com.red_velvet.marvel.domain.mapper.LocalEventMapper +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +object RepositoryModule { + + @Singleton + @Provides + fun provideMarvelRepository( + marvelService: MarvelService, + marvelDatabase: MarvelDatabase, + comicsEntityMapper: ComicEntityMapper, + localComicMapper: LocalComicMapper, + eventEntityMapper: EventEntityMapper, + localEventMapper: LocalEventMapper, + characterEntityMapper: CharacterEntityMapper, + localCharacterMapper: LocalCharacterMapper, + ): MarvelRepository { + return MarvelRepositoryImpl( + marvelService, + marvelDatabase, + comicsEntityMapper, + localComicMapper, + eventEntityMapper, + localEventMapper, + characterEntityMapper, + localCharacterMapper, + ) + } + + @Singleton + @Provides + fun provideComicEntityMapper(): ComicEntityMapper { + return ComicEntityMapper() + } + + @Singleton + @Provides + fun provideLocalComicMapper(): LocalComicMapper { + return LocalComicMapper() + } + + @Singleton + @Provides + fun provideEventEntityMapper(): EventEntityMapper { + return EventEntityMapper() + } + + @Singleton + @Provides + fun provideLocalEventMapper(): LocalEventMapper { + return LocalEventMapper() + } + + @Singleton + @Provides + fun provideCharacterEntityMapper(): CharacterEntityMapper { + return CharacterEntityMapper() + } + + @Singleton + @Provides + fun provideLocalCharacterMapper(): LocalCharacterMapper { + return LocalCharacterMapper() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/red_velvet/marvel/domain/mapper/CharacterMapper.kt b/app/src/main/java/com/red_velvet/marvel/domain/mapper/CharacterMapper.kt new file mode 100644 index 00000000..ed847e45 --- /dev/null +++ b/app/src/main/java/com/red_velvet/marvel/domain/mapper/CharacterMapper.kt @@ -0,0 +1,15 @@ +package com.red_velvet.marvel.domain.mapper + +import com.red_velvet.marvel.data.remote.dto.CharacterDto +import com.red_velvet.marvel.domain.model.Character +import com.red_velvet.marvel.domain.util.toUrl + +class CharacterMapper : Mapper { + override fun map(input: CharacterDto): Character { + return Character( + id = input.id ?: 0, + name = input.name ?: "", + imageUrl = input.thumbnail?.toUrl() ?: "" + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/red_velvet/marvel/domain/mapper/ComicMapper.kt b/app/src/main/java/com/red_velvet/marvel/domain/mapper/ComicMapper.kt new file mode 100644 index 00000000..a3f69f21 --- /dev/null +++ b/app/src/main/java/com/red_velvet/marvel/domain/mapper/ComicMapper.kt @@ -0,0 +1,16 @@ +package com.red_velvet.marvel.domain.mapper + +import com.red_velvet.marvel.data.remote.dto.ComicDto +import com.red_velvet.marvel.domain.model.Comic +import com.red_velvet.marvel.domain.util.toUrl + +class ComicMapper : Mapper { + override fun map(input: ComicDto): Comic { + return Comic( + id = input.id ?: 0, + title = input.title ?: "", + imageUrl = input.thumbnail?.toUrl() ?: "", + ) + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/red_velvet/marvel/domain/mapper/EventMapper.kt b/app/src/main/java/com/red_velvet/marvel/domain/mapper/EventMapper.kt new file mode 100644 index 00000000..b07720dd --- /dev/null +++ b/app/src/main/java/com/red_velvet/marvel/domain/mapper/EventMapper.kt @@ -0,0 +1,15 @@ +package com.red_velvet.marvel.domain.mapper + +import com.red_velvet.marvel.data.remote.dto.EventDto +import com.red_velvet.marvel.domain.model.Event +import com.red_velvet.marvel.domain.util.toUrl + +class EventMapper : Mapper { + override fun map(input: EventDto): Event { + return Event( + id = input.id ?: 0, + title = input.title ?: "", + imageUrl = input.thumbnail?.toUrl() ?: "", + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/red_velvet/marvel/domain/mapper/LocalCharacterMapper.kt b/app/src/main/java/com/red_velvet/marvel/domain/mapper/LocalCharacterMapper.kt new file mode 100644 index 00000000..95f35be6 --- /dev/null +++ b/app/src/main/java/com/red_velvet/marvel/domain/mapper/LocalCharacterMapper.kt @@ -0,0 +1,14 @@ +package com.red_velvet.marvel.domain.mapper + +import com.red_velvet.marvel.data.local.database.entity.CharacterEntity +import com.red_velvet.marvel.domain.model.Character + +class LocalCharacterMapper : Mapper { + override fun map(input: CharacterEntity): Character { + return Character( + id = input.id, + name = input.name, + imageUrl = input.imageUrl, + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/red_velvet/marvel/domain/mapper/LocalComicMapper.kt b/app/src/main/java/com/red_velvet/marvel/domain/mapper/LocalComicMapper.kt new file mode 100644 index 00000000..4ce81723 --- /dev/null +++ b/app/src/main/java/com/red_velvet/marvel/domain/mapper/LocalComicMapper.kt @@ -0,0 +1,14 @@ +package com.red_velvet.marvel.domain.mapper + +import com.red_velvet.marvel.data.local.database.entity.ComicEntity +import com.red_velvet.marvel.domain.model.Comic + +class LocalComicMapper : Mapper { + override fun map(input: ComicEntity): Comic { + return Comic( + id = input.id, + title = input.title, + imageUrl = input.imageUrl, + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/red_velvet/marvel/domain/mapper/LocalEventMapper.kt b/app/src/main/java/com/red_velvet/marvel/domain/mapper/LocalEventMapper.kt new file mode 100644 index 00000000..b96989b8 --- /dev/null +++ b/app/src/main/java/com/red_velvet/marvel/domain/mapper/LocalEventMapper.kt @@ -0,0 +1,14 @@ +package com.red_velvet.marvel.domain.mapper + +import com.red_velvet.marvel.data.local.database.entity.EventEntity +import com.red_velvet.marvel.domain.model.Event + +class LocalEventMapper : Mapper { + override fun map(input: EventEntity): Event { + return Event( + id = input.id, + title = input.title, + imageUrl = input.imageUrl, + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/red_velvet/marvel/domain/mapper/Mapper.kt b/app/src/main/java/com/red_velvet/marvel/domain/mapper/Mapper.kt new file mode 100644 index 00000000..70f3a589 --- /dev/null +++ b/app/src/main/java/com/red_velvet/marvel/domain/mapper/Mapper.kt @@ -0,0 +1,5 @@ +package com.red_velvet.marvel.domain.mapper + +interface Mapper { + fun map(input: I): O +} \ No newline at end of file diff --git a/app/src/main/java/com/red_velvet/marvel/domain/model/Character.kt b/app/src/main/java/com/red_velvet/marvel/domain/model/Character.kt new file mode 100644 index 00000000..081bf2d1 --- /dev/null +++ b/app/src/main/java/com/red_velvet/marvel/domain/model/Character.kt @@ -0,0 +1,7 @@ +package com.red_velvet.marvel.domain.model + +data class Character( + val id: Int, + val name: String, + val imageUrl: String, +) diff --git a/app/src/main/java/com/red_velvet/marvel/domain/model/Comic.kt b/app/src/main/java/com/red_velvet/marvel/domain/model/Comic.kt new file mode 100644 index 00000000..1a5719bf --- /dev/null +++ b/app/src/main/java/com/red_velvet/marvel/domain/model/Comic.kt @@ -0,0 +1,7 @@ +package com.red_velvet.marvel.domain.model + +data class Comic( + val id: Int, + val title: String, + val imageUrl: String, +) diff --git a/app/src/main/java/com/red_velvet/marvel/domain/model/Event.kt b/app/src/main/java/com/red_velvet/marvel/domain/model/Event.kt new file mode 100644 index 00000000..35c80d9b --- /dev/null +++ b/app/src/main/java/com/red_velvet/marvel/domain/model/Event.kt @@ -0,0 +1,7 @@ +package com.red_velvet.marvel.domain.model + +data class Event( + val id: Int, + val title: String, + val imageUrl: String, +) diff --git a/app/src/main/java/com/red_velvet/marvel/domain/util/Extention.kt b/app/src/main/java/com/red_velvet/marvel/domain/util/Extention.kt new file mode 100644 index 00000000..e535dbce --- /dev/null +++ b/app/src/main/java/com/red_velvet/marvel/domain/util/Extention.kt @@ -0,0 +1,5 @@ +package com.red_velvet.marvel.domain.util + +import com.red_velvet.marvel.data.remote.dto.ThumbnailDto + +fun ThumbnailDto.toUrl() = this.path + "." + this.extension diff --git a/app/src/main/java/com/red_velvet/marvel/ui/MainActivity.kt b/app/src/main/java/com/red_velvet/marvel/ui/MainActivity.kt index 63a8f0cf..f2aa3594 100644 --- a/app/src/main/java/com/red_velvet/marvel/ui/MainActivity.kt +++ b/app/src/main/java/com/red_velvet/marvel/ui/MainActivity.kt @@ -10,7 +10,9 @@ import com.red_velvet.marvel.databinding.ActivityMainBinding import com.red_velvet.marvel.ui.base.BaseActivity import com.red_velvet.marvel.ui.utils.hideView import com.red_velvet.marvel.ui.utils.showView +import dagger.hilt.android.AndroidEntryPoint +@AndroidEntryPoint class MainActivity : BaseActivity() { override val LOG_TAG: String = "MainActivity" diff --git a/app/src/main/java/com/red_velvet/marvel/ui/base/BaseViewModel.kt b/app/src/main/java/com/red_velvet/marvel/ui/base/BaseViewModel.kt index 4ba83050..2fe6973c 100644 --- a/app/src/main/java/com/red_velvet/marvel/ui/base/BaseViewModel.kt +++ b/app/src/main/java/com/red_velvet/marvel/ui/base/BaseViewModel.kt @@ -37,5 +37,24 @@ abstract class BaseViewModel : ViewModel() { } } + fun bindObservable( + stateObservable: Observable, + onError: (Throwable) -> Unit, + onNext: (T) -> Unit + ) { + try { + stateObservable + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribeBy( + onError = onError, + onNext = onNext, + ) + .addTo(compositeDisposable) + } catch (e: Exception) { + onError(e) + } + } + } diff --git a/app/src/main/java/com/red_velvet/marvel/ui/characterDetails/CharacterComicsAdapter.kt b/app/src/main/java/com/red_velvet/marvel/ui/characterDetails/CharacterComicsAdapter.kt index 4f371cbc..c380a921 100644 --- a/app/src/main/java/com/red_velvet/marvel/ui/characterDetails/CharacterComicsAdapter.kt +++ b/app/src/main/java/com/red_velvet/marvel/ui/characterDetails/CharacterComicsAdapter.kt @@ -1,12 +1,12 @@ package com.red_velvet.marvel.ui.characterDetails import com.red_velvet.marvel.R -import com.red_velvet.marvel.data.model.Comic +import com.red_velvet.marvel.data.remote.dto.ComicDto import com.red_velvet.marvel.ui.base.BaseAdapter import com.red_velvet.marvel.ui.base.BaseInteractionListener -class ComicsByCharacterAdapter(items: List, listener: SeriesInteractionListener) : - BaseAdapter(items, listener) { +class ComicsByCharacterAdapter(items: List, listener: SeriesInteractionListener) : + BaseAdapter(items, listener) { override val layoutId: Int = R.layout.item_character_comics } diff --git a/app/src/main/java/com/red_velvet/marvel/ui/characterDetails/CharacterDetailsFragment.kt b/app/src/main/java/com/red_velvet/marvel/ui/characterDetails/CharacterDetailsFragment.kt index 617a9cc9..db304d0d 100644 --- a/app/src/main/java/com/red_velvet/marvel/ui/characterDetails/CharacterDetailsFragment.kt +++ b/app/src/main/java/com/red_velvet/marvel/ui/characterDetails/CharacterDetailsFragment.kt @@ -8,7 +8,9 @@ import androidx.navigation.fragment.navArgs import com.red_velvet.marvel.R import com.red_velvet.marvel.databinding.FragmentCharacterBinding import com.red_velvet.marvel.ui.base.BaseFragment +import dagger.hilt.android.AndroidEntryPoint +@AndroidEntryPoint class CharacterDetailsFragment : BaseFragment() { diff --git a/app/src/main/java/com/red_velvet/marvel/ui/characterDetails/CharacterDetailsViewModel.kt b/app/src/main/java/com/red_velvet/marvel/ui/characterDetails/CharacterDetailsViewModel.kt index ec81fa9b..93baa35b 100644 --- a/app/src/main/java/com/red_velvet/marvel/ui/characterDetails/CharacterDetailsViewModel.kt +++ b/app/src/main/java/com/red_velvet/marvel/ui/characterDetails/CharacterDetailsViewModel.kt @@ -2,31 +2,30 @@ package com.red_velvet.marvel.ui.characterDetails import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData -import com.red_velvet.marvel.data.model.Character -import com.red_velvet.marvel.data.model.Comic -import com.red_velvet.marvel.data.model.Series -import com.red_velvet.marvel.data.remote.RetrofitClient +import com.red_velvet.marvel.data.remote.dto.CharacterDto +import com.red_velvet.marvel.data.remote.dto.ComicDto +import com.red_velvet.marvel.data.remote.dto.SeriesDto import com.red_velvet.marvel.data.repository.MarvelRepository -import com.red_velvet.marvel.data.repository.MarvelRepositoryImpl import com.red_velvet.marvel.ui.base.BaseViewModel import com.red_velvet.marvel.ui.utils.SingleEvent import com.red_velvet.marvel.ui.utils.State +import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject -class CharacterDetailsViewModel : BaseViewModel(), SeriesInteractionListener, +@HiltViewModel +class CharacterDetailsViewModel @Inject constructor( + private val repository: MarvelRepository, +) : BaseViewModel(), SeriesInteractionListener, ComicsInteractionListener { - private val repository: MarvelRepository by lazy { - MarvelRepositoryImpl(RetrofitClient.apiService) - } - - private val _characterDetails: MutableLiveData>> = MutableLiveData() - val characterDetails: LiveData>> = _characterDetails + private val _characterDetails: MutableLiveData>> = MutableLiveData() + val characterDetails: LiveData>> = _characterDetails - private val _comics: MutableLiveData>> = MutableLiveData() - val comics: LiveData>> = _comics + private val _comics: MutableLiveData>> = MutableLiveData() + val comics: LiveData>> = _comics - private val _series: MutableLiveData>> = MutableLiveData() - val series: LiveData>> = _series + private val _series: MutableLiveData>> = MutableLiveData() + val series: LiveData>> = _series private val _navigationToComicDetails: MutableLiveData> = MutableLiveData() val navigationToComicDetails: LiveData> = _navigationToComicDetails @@ -48,7 +47,7 @@ class CharacterDetailsViewModel : BaseViewModel(), SeriesInteractionListener, ) } - private fun onGetCharacterState(state: State>) { + private fun onGetCharacterState(state: State>) { _characterDetails.postValue(state) } @@ -64,7 +63,7 @@ class CharacterDetailsViewModel : BaseViewModel(), SeriesInteractionListener, ) } - private fun onGetComicsByCharacterIdState(state: State>) { + private fun onGetComicsByCharacterIdState(state: State>) { _comics.postValue(state) } @@ -80,7 +79,7 @@ class CharacterDetailsViewModel : BaseViewModel(), SeriesInteractionListener, ) } - private fun onGetSeriesByCharacterIdState(state: State>) { + private fun onGetSeriesByCharacterIdState(state: State>) { _series.postValue(state) } diff --git a/app/src/main/java/com/red_velvet/marvel/ui/characterDetails/CharacterSeriesAdapter.kt b/app/src/main/java/com/red_velvet/marvel/ui/characterDetails/CharacterSeriesAdapter.kt index 270fcf51..9fb90ce5 100644 --- a/app/src/main/java/com/red_velvet/marvel/ui/characterDetails/CharacterSeriesAdapter.kt +++ b/app/src/main/java/com/red_velvet/marvel/ui/characterDetails/CharacterSeriesAdapter.kt @@ -1,12 +1,12 @@ package com.red_velvet.marvel.ui.characterDetails import com.red_velvet.marvel.R -import com.red_velvet.marvel.data.model.Series +import com.red_velvet.marvel.data.remote.dto.SeriesDto import com.red_velvet.marvel.ui.base.BaseAdapter import com.red_velvet.marvel.ui.base.BaseInteractionListener -class CharacterSeriesAdapter(items: List, listener: SeriesInteractionListener) : - BaseAdapter(items, listener) { +class CharacterSeriesAdapter(items: List, listener: SeriesInteractionListener) : + BaseAdapter(items, listener) { override val layoutId: Int = R.layout.item_character_series } diff --git a/app/src/main/java/com/red_velvet/marvel/ui/characters/CharactersAdapter.kt b/app/src/main/java/com/red_velvet/marvel/ui/characters/CharactersAdapter.kt index d073e739..7b5e4dea 100644 --- a/app/src/main/java/com/red_velvet/marvel/ui/characters/CharactersAdapter.kt +++ b/app/src/main/java/com/red_velvet/marvel/ui/characters/CharactersAdapter.kt @@ -1,14 +1,14 @@ package com.red_velvet.marvel.ui.characters import com.red_velvet.marvel.R -import com.red_velvet.marvel.data.model.Character +import com.red_velvet.marvel.data.remote.dto.CharacterDto import com.red_velvet.marvel.ui.base.BaseAdapter import com.red_velvet.marvel.ui.base.BaseInteractionListener class CharactersAdapter( - items: List, + items: List, listener: CharacterDetailsInteractionListener -) : BaseAdapter(items, listener) { +) : BaseAdapter(items, listener) { override val layoutId: Int = R.layout.characters_item } diff --git a/app/src/main/java/com/red_velvet/marvel/ui/characters/CharactersFragment.kt b/app/src/main/java/com/red_velvet/marvel/ui/characters/CharactersFragment.kt index 74632d43..74b98189 100644 --- a/app/src/main/java/com/red_velvet/marvel/ui/characters/CharactersFragment.kt +++ b/app/src/main/java/com/red_velvet/marvel/ui/characters/CharactersFragment.kt @@ -7,7 +7,9 @@ import androidx.navigation.fragment.findNavController import com.red_velvet.marvel.R import com.red_velvet.marvel.databinding.FragmentCharactersBinding import com.red_velvet.marvel.ui.base.BaseFragment +import dagger.hilt.android.AndroidEntryPoint +@AndroidEntryPoint class CharactersFragment : BaseFragment() { override val layoutIdFragment = R.layout.fragment_characters diff --git a/app/src/main/java/com/red_velvet/marvel/ui/characters/CharactersViewModel.kt b/app/src/main/java/com/red_velvet/marvel/ui/characters/CharactersViewModel.kt index 57c7bc46..d729a109 100644 --- a/app/src/main/java/com/red_velvet/marvel/ui/characters/CharactersViewModel.kt +++ b/app/src/main/java/com/red_velvet/marvel/ui/characters/CharactersViewModel.kt @@ -2,27 +2,26 @@ package com.red_velvet.marvel.ui.characters import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData -import com.red_velvet.marvel.data.model.Character -import com.red_velvet.marvel.data.remote.RetrofitClient +import com.red_velvet.marvel.data.remote.dto.CharacterDto import com.red_velvet.marvel.data.repository.MarvelRepository -import com.red_velvet.marvel.data.repository.MarvelRepositoryImpl import com.red_velvet.marvel.ui.base.BaseViewModel import com.red_velvet.marvel.ui.utils.SingleEvent import com.red_velvet.marvel.ui.utils.State +import dagger.hilt.android.lifecycle.HiltViewModel import io.reactivex.rxjava3.core.Observable import io.reactivex.rxjava3.kotlin.addTo import java.util.concurrent.TimeUnit +import javax.inject.Inject -class CharactersViewModel : BaseViewModel(), CharacterDetailsInteractionListener { - private val _characters: MutableLiveData>> = MutableLiveData() - val characters: LiveData>> = _characters +@HiltViewModel +class CharactersViewModel @Inject constructor( + private val repository: MarvelRepository, +) : BaseViewModel(), CharacterDetailsInteractionListener { + private val _characters: MutableLiveData>> = MutableLiveData() + val characters: LiveData>> = _characters val searchQuery = MutableLiveData() - private val repository: MarvelRepository by lazy { - MarvelRepositoryImpl(RetrofitClient.apiService) - } - private val _navigationToCharacterDetails: MutableLiveData> = MutableLiveData() val navigationToCharacterDetails: LiveData> = _navigationToCharacterDetails @@ -55,7 +54,7 @@ class CharactersViewModel : BaseViewModel(), CharacterDetailsInteractionListener ) } - private fun onGetCharactersState(state: State>) { + private fun onGetCharactersState(state: State>) { _characters.postValue(state) } diff --git a/app/src/main/java/com/red_velvet/marvel/ui/comicDetails/ComicDetailsCharactersAdapter.kt b/app/src/main/java/com/red_velvet/marvel/ui/comicDetails/ComicDetailsCharactersAdapter.kt index 6e1c45f2..787f416d 100644 --- a/app/src/main/java/com/red_velvet/marvel/ui/comicDetails/ComicDetailsCharactersAdapter.kt +++ b/app/src/main/java/com/red_velvet/marvel/ui/comicDetails/ComicDetailsCharactersAdapter.kt @@ -1,14 +1,14 @@ package com.red_velvet.marvel.ui.comicDetails import com.red_velvet.marvel.R -import com.red_velvet.marvel.data.model.Character +import com.red_velvet.marvel.data.remote.dto.CharacterDto import com.red_velvet.marvel.ui.base.BaseAdapter import com.red_velvet.marvel.ui.base.BaseInteractionListener class ComicDetailsCharactersAdapter( - items: List, + items: List, listener: ComicDetailsCharacterListenerInteraction, -) : BaseAdapter(items, listener) { +) : BaseAdapter(items, listener) { override val layoutId: Int = R.layout.item_comic_character } diff --git a/app/src/main/java/com/red_velvet/marvel/ui/comicDetails/ComicDetailsCreatorsAdapter.kt b/app/src/main/java/com/red_velvet/marvel/ui/comicDetails/ComicDetailsCreatorsAdapter.kt index f28c43d6..d9276b59 100644 --- a/app/src/main/java/com/red_velvet/marvel/ui/comicDetails/ComicDetailsCreatorsAdapter.kt +++ b/app/src/main/java/com/red_velvet/marvel/ui/comicDetails/ComicDetailsCreatorsAdapter.kt @@ -1,14 +1,14 @@ package com.red_velvet.marvel.ui.comicDetails import com.red_velvet.marvel.R -import com.red_velvet.marvel.data.model.Creator +import com.red_velvet.marvel.data.remote.dto.CreatorDto import com.red_velvet.marvel.ui.base.BaseAdapter import com.red_velvet.marvel.ui.base.BaseInteractionListener class ComicDetailsCreatorsAdapter( - items: List, + items: List, listener: ComicDetailsCreatorListenerInteraction, -) : BaseAdapter(items, listener) { +) : BaseAdapter(items, listener) { override val layoutId: Int = R.layout.item_comic_creator } diff --git a/app/src/main/java/com/red_velvet/marvel/ui/comicDetails/ComicDetailsFragment.kt b/app/src/main/java/com/red_velvet/marvel/ui/comicDetails/ComicDetailsFragment.kt index 37d7fb5c..a9276055 100644 --- a/app/src/main/java/com/red_velvet/marvel/ui/comicDetails/ComicDetailsFragment.kt +++ b/app/src/main/java/com/red_velvet/marvel/ui/comicDetails/ComicDetailsFragment.kt @@ -8,7 +8,9 @@ import androidx.navigation.fragment.navArgs import com.red_velvet.marvel.R import com.red_velvet.marvel.databinding.FragmentComicDetailsBinding import com.red_velvet.marvel.ui.base.BaseFragment +import dagger.hilt.android.AndroidEntryPoint +@AndroidEntryPoint class ComicDetailsFragment : BaseFragment() { override val layoutIdFragment = R.layout.fragment_comic_details diff --git a/app/src/main/java/com/red_velvet/marvel/ui/comicDetails/ComicDetailsViewModel.kt b/app/src/main/java/com/red_velvet/marvel/ui/comicDetails/ComicDetailsViewModel.kt index 70e2e82e..502fa451 100644 --- a/app/src/main/java/com/red_velvet/marvel/ui/comicDetails/ComicDetailsViewModel.kt +++ b/app/src/main/java/com/red_velvet/marvel/ui/comicDetails/ComicDetailsViewModel.kt @@ -2,31 +2,30 @@ package com.red_velvet.marvel.ui.comicDetails import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData -import com.red_velvet.marvel.data.model.Character -import com.red_velvet.marvel.data.model.Comic -import com.red_velvet.marvel.data.model.Creator -import com.red_velvet.marvel.data.remote.RetrofitClient +import com.red_velvet.marvel.data.remote.dto.CharacterDto +import com.red_velvet.marvel.data.remote.dto.ComicDto +import com.red_velvet.marvel.data.remote.dto.CreatorDto import com.red_velvet.marvel.data.repository.MarvelRepository -import com.red_velvet.marvel.data.repository.MarvelRepositoryImpl import com.red_velvet.marvel.ui.base.BaseViewModel import com.red_velvet.marvel.ui.utils.SingleEvent import com.red_velvet.marvel.ui.utils.State +import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject -class ComicDetailsViewModel : BaseViewModel(), ComicDetailsCreatorListenerInteraction, +@HiltViewModel +class ComicDetailsViewModel @Inject constructor( + private val repository: MarvelRepository, +) : BaseViewModel(), ComicDetailsCreatorListenerInteraction, ComicDetailsCharacterListenerInteraction { - private val _comicsDetails: MutableLiveData>> = MutableLiveData() - val comicsDetails: LiveData>> = _comicsDetails + private val _comicsDetails: MutableLiveData>> = MutableLiveData() + val comicsDetails: LiveData>> = _comicsDetails - private val _creators: MutableLiveData>> = MutableLiveData() - val creators: LiveData>> = _creators + private val _creators: MutableLiveData>> = MutableLiveData() + val creators: LiveData>> = _creators - private val _characters: MutableLiveData>> = MutableLiveData() - val characters: LiveData>> = _characters - - private val repository: MarvelRepository by lazy { - MarvelRepositoryImpl(RetrofitClient.apiService) - } + private val _characters: MutableLiveData>> = MutableLiveData() + val characters: LiveData>> = _characters private val _navigationToCharacterDetails: MutableLiveData> = MutableLiveData() val navigationToCharacterDetails: LiveData> = _navigationToCharacterDetails @@ -62,7 +61,7 @@ class ComicDetailsViewModel : BaseViewModel(), ComicDetailsCreatorListenerIntera ) } - private fun onGetComicState(state: State>) { + private fun onGetComicState(state: State>) { _comicsDetails.postValue(state) } @@ -70,7 +69,7 @@ class ComicDetailsViewModel : BaseViewModel(), ComicDetailsCreatorListenerIntera _comicsDetails.postValue(State.Failed(e.message.toString())) } - private fun onGetCreatorsByComicIdState(state: State>) { + private fun onGetCreatorsByComicIdState(state: State>) { _creators.postValue(state) } @@ -78,7 +77,7 @@ class ComicDetailsViewModel : BaseViewModel(), ComicDetailsCreatorListenerIntera _creators.postValue(State.Failed(e.message.toString())) } - private fun onGetCharactersByComicIdState(state: State>) { + private fun onGetCharactersByComicIdState(state: State>) { _characters.postValue(state) } diff --git a/app/src/main/java/com/red_velvet/marvel/ui/eventDetails/CharactersAdapter.kt b/app/src/main/java/com/red_velvet/marvel/ui/eventDetails/CharactersAdapter.kt index 99c6bab4..7ac5d1bf 100644 --- a/app/src/main/java/com/red_velvet/marvel/ui/eventDetails/CharactersAdapter.kt +++ b/app/src/main/java/com/red_velvet/marvel/ui/eventDetails/CharactersAdapter.kt @@ -1,12 +1,12 @@ package com.red_velvet.marvel.ui.eventDetails import com.red_velvet.marvel.R -import com.red_velvet.marvel.data.model.Character +import com.red_velvet.marvel.data.remote.dto.CharacterDto import com.red_velvet.marvel.ui.base.BaseAdapter import com.red_velvet.marvel.ui.base.BaseInteractionListener -class CharactersAdapter(items: List, listener: CharactersInteractionListener) : - BaseAdapter(items, listener) { +class CharactersAdapter(items: List, listener: CharactersInteractionListener) : + BaseAdapter(items, listener) { override val layoutId: Int = R.layout.item_charactors } diff --git a/app/src/main/java/com/red_velvet/marvel/ui/eventDetails/CreatorsAdapter.kt b/app/src/main/java/com/red_velvet/marvel/ui/eventDetails/CreatorsAdapter.kt index 462beb35..6bf3409f 100644 --- a/app/src/main/java/com/red_velvet/marvel/ui/eventDetails/CreatorsAdapter.kt +++ b/app/src/main/java/com/red_velvet/marvel/ui/eventDetails/CreatorsAdapter.kt @@ -1,12 +1,12 @@ package com.red_velvet.marvel.ui.eventDetails import com.red_velvet.marvel.R -import com.red_velvet.marvel.data.model.Creator +import com.red_velvet.marvel.data.remote.dto.CreatorDto import com.red_velvet.marvel.ui.base.BaseAdapter import com.red_velvet.marvel.ui.base.BaseInteractionListener -class CreatorsAdapter(items: List, listener: CreatorsInteractionListener) : - BaseAdapter(items, listener) { +class CreatorsAdapter(items: List, listener: CreatorsInteractionListener) : + BaseAdapter(items, listener) { override val layoutId: Int = R.layout.item_creators_event } diff --git a/app/src/main/java/com/red_velvet/marvel/ui/eventDetails/EventDetailViewModel.kt b/app/src/main/java/com/red_velvet/marvel/ui/eventDetails/EventDetailViewModel.kt index 4682f95f..58aec4d8 100644 --- a/app/src/main/java/com/red_velvet/marvel/ui/eventDetails/EventDetailViewModel.kt +++ b/app/src/main/java/com/red_velvet/marvel/ui/eventDetails/EventDetailViewModel.kt @@ -2,28 +2,30 @@ package com.red_velvet.marvel.ui.eventDetails import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData -import com.red_velvet.marvel.data.model.Character -import com.red_velvet.marvel.data.model.Creator -import com.red_velvet.marvel.data.model.Event -import com.red_velvet.marvel.data.remote.RetrofitClient -import com.red_velvet.marvel.data.repository.MarvelRepositoryImpl +import com.red_velvet.marvel.data.remote.dto.CharacterDto +import com.red_velvet.marvel.data.remote.dto.CreatorDto +import com.red_velvet.marvel.data.remote.dto.EventDto +import com.red_velvet.marvel.data.repository.MarvelRepository import com.red_velvet.marvel.ui.base.BaseViewModel import com.red_velvet.marvel.ui.utils.SingleEvent import com.red_velvet.marvel.ui.utils.State +import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject -class EventDetailViewModel : BaseViewModel(), CharactersInteractionListener, +@HiltViewModel +class EventDetailViewModel @Inject constructor( + private val repository: MarvelRepository +) : BaseViewModel(), CharactersInteractionListener, CreatorsInteractionListener { - private val repository by lazy { MarvelRepositoryImpl(RetrofitClient.apiService) } + private var _event: MutableLiveData>> = MutableLiveData() + val event: MutableLiveData>> = _event - private var _event: MutableLiveData>> = MutableLiveData() - val event: MutableLiveData>> = _event + private var _characters: MutableLiveData>> = MutableLiveData() + val characters: MutableLiveData>> = _characters - private var _characters: MutableLiveData>> = MutableLiveData() - val characters: MutableLiveData>> = _characters - - private var _creators: MutableLiveData>> = MutableLiveData() - val creators: MutableLiveData>> = _creators + private var _creators: MutableLiveData>> = MutableLiveData() + val creators: MutableLiveData>> = _creators private val _navigationToCharacterDetails: MutableLiveData> = MutableLiveData() val navigationToCharacterDetails: LiveData> = _navigationToCharacterDetails @@ -58,7 +60,7 @@ class EventDetailViewModel : BaseViewModel(), CharactersInteractionListener, ) } - private fun onGetEventState(state: State>) { + private fun onGetEventState(state: State>) { _event.postValue(state) } @@ -66,7 +68,7 @@ class EventDetailViewModel : BaseViewModel(), CharactersInteractionListener, _event.postValue(State.Failed(e.message.toString())) } - private fun onGetEventCreatorsState(state: State>) { + private fun onGetEventCreatorsState(state: State>) { _creators.postValue(state) } @@ -74,7 +76,7 @@ class EventDetailViewModel : BaseViewModel(), CharactersInteractionListener, _creators.postValue(State.Failed(e.message.toString())) } - private fun onGetEventCharactersState(state: State>) { + private fun onGetEventCharactersState(state: State>) { _characters.postValue(state) } diff --git a/app/src/main/java/com/red_velvet/marvel/ui/eventDetails/EventDetailsFragment.kt b/app/src/main/java/com/red_velvet/marvel/ui/eventDetails/EventDetailsFragment.kt index d5f741c7..d18ca3fa 100644 --- a/app/src/main/java/com/red_velvet/marvel/ui/eventDetails/EventDetailsFragment.kt +++ b/app/src/main/java/com/red_velvet/marvel/ui/eventDetails/EventDetailsFragment.kt @@ -9,8 +9,9 @@ import androidx.navigation.fragment.navArgs import com.red_velvet.marvel.R import com.red_velvet.marvel.databinding.FragmentEventDetailsBinding import com.red_velvet.marvel.ui.base.BaseFragment +import dagger.hilt.android.AndroidEntryPoint - +@AndroidEntryPoint class EventDetailsFragment : BaseFragment() { override val layoutIdFragment = R.layout.fragment_event_details diff --git a/app/src/main/java/com/red_velvet/marvel/ui/events/EventsAdapter.kt b/app/src/main/java/com/red_velvet/marvel/ui/events/EventsAdapter.kt index 5c8a9b45..0cf2bcb6 100644 --- a/app/src/main/java/com/red_velvet/marvel/ui/events/EventsAdapter.kt +++ b/app/src/main/java/com/red_velvet/marvel/ui/events/EventsAdapter.kt @@ -1,12 +1,12 @@ package com.red_velvet.marvel.ui.events import com.red_velvet.marvel.R -import com.red_velvet.marvel.data.model.Event +import com.red_velvet.marvel.data.remote.dto.EventDto import com.red_velvet.marvel.ui.base.BaseAdapter import com.red_velvet.marvel.ui.base.BaseInteractionListener -class EventsAdapter(items: List, listener: EventsInteractionListener) : - BaseAdapter(items, listener) { +class EventsAdapter(items: List, listener: EventsInteractionListener) : + BaseAdapter(items, listener) { override val layoutId: Int = R.layout.item_event } diff --git a/app/src/main/java/com/red_velvet/marvel/ui/events/EventsFragment.kt b/app/src/main/java/com/red_velvet/marvel/ui/events/EventsFragment.kt index f7415ee9..bec41fdc 100644 --- a/app/src/main/java/com/red_velvet/marvel/ui/events/EventsFragment.kt +++ b/app/src/main/java/com/red_velvet/marvel/ui/events/EventsFragment.kt @@ -8,8 +8,9 @@ import androidx.navigation.fragment.findNavController import com.red_velvet.marvel.R import com.red_velvet.marvel.databinding.FragmentEventsBinding import com.red_velvet.marvel.ui.base.BaseFragment +import dagger.hilt.android.AndroidEntryPoint - +@AndroidEntryPoint class EventsFragment : BaseFragment() { override val layoutIdFragment: Int = R.layout.fragment_events diff --git a/app/src/main/java/com/red_velvet/marvel/ui/events/EventsViewModel.kt b/app/src/main/java/com/red_velvet/marvel/ui/events/EventsViewModel.kt index 11d3ce47..1debf1c0 100644 --- a/app/src/main/java/com/red_velvet/marvel/ui/events/EventsViewModel.kt +++ b/app/src/main/java/com/red_velvet/marvel/ui/events/EventsViewModel.kt @@ -2,22 +2,24 @@ package com.red_velvet.marvel.ui.events import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData -import com.red_velvet.marvel.data.model.Event -import com.red_velvet.marvel.data.remote.RetrofitClient -import com.red_velvet.marvel.data.repository.MarvelRepositoryImpl +import com.red_velvet.marvel.data.remote.dto.EventDto +import com.red_velvet.marvel.data.repository.MarvelRepository import com.red_velvet.marvel.ui.base.BaseViewModel import com.red_velvet.marvel.ui.utils.SingleEvent import com.red_velvet.marvel.ui.utils.State +import dagger.hilt.android.lifecycle.HiltViewModel import io.reactivex.rxjava3.core.Observable import io.reactivex.rxjava3.kotlin.addTo import java.util.concurrent.TimeUnit +import javax.inject.Inject -class EventsViewModel : BaseViewModel(), EventsInteractionListener { +@HiltViewModel +class EventsViewModel @Inject constructor( + private val repository: MarvelRepository +) : BaseViewModel(), EventsInteractionListener { - private val repository by lazy { MarvelRepositoryImpl(RetrofitClient.apiService) } - - private val _events = MutableLiveData>>() - val events: LiveData>> = _events + private val _events = MutableLiveData>>() + val events: LiveData>> = _events private val _navigationToEventDetails = MutableLiveData>() val navigationToEventDetails: LiveData> = _navigationToEventDetails @@ -37,7 +39,7 @@ class EventsViewModel : BaseViewModel(), EventsInteractionListener { ) } - private fun onGetAllEventsState(state: State>) { + private fun onGetAllEventsState(state: State>) { _events.postValue(state) } diff --git a/app/src/main/java/com/red_velvet/marvel/ui/home/HomeFragment.kt b/app/src/main/java/com/red_velvet/marvel/ui/home/HomeFragment.kt index ef9a287e..10c47ec9 100644 --- a/app/src/main/java/com/red_velvet/marvel/ui/home/HomeFragment.kt +++ b/app/src/main/java/com/red_velvet/marvel/ui/home/HomeFragment.kt @@ -10,7 +10,9 @@ import com.red_velvet.marvel.ui.base.BaseFragment import com.red_velvet.marvel.ui.home.adapter.CharactersAdapter import com.red_velvet.marvel.ui.home.adapter.ComicsAdapter import com.red_velvet.marvel.ui.home.adapter.EventsAdapter +import dagger.hilt.android.AndroidEntryPoint +@AndroidEntryPoint class HomeFragment : BaseFragment() { override val layoutIdFragment = R.layout.fragment_home @@ -28,13 +30,6 @@ class HomeFragment : BaseFragment() { recyclerChars.adapter = charsAdapter recyclerEvents.adapter = eventsAdapter } - binding.textViewError.setOnClickListener { - viewModel.apply { - getCharacters() - getComics() - getEvents() - } - } initNavigateToComicDetails() } @@ -63,5 +58,4 @@ class HomeFragment : BaseFragment() { } } } - } \ No newline at end of file diff --git a/app/src/main/java/com/red_velvet/marvel/ui/home/HomeViewModel.kt b/app/src/main/java/com/red_velvet/marvel/ui/home/HomeViewModel.kt index a009af1b..900fac7d 100644 --- a/app/src/main/java/com/red_velvet/marvel/ui/home/HomeViewModel.kt +++ b/app/src/main/java/com/red_velvet/marvel/ui/home/HomeViewModel.kt @@ -2,21 +2,19 @@ package com.red_velvet.marvel.ui.home import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData -import com.red_velvet.marvel.data.model.Character -import com.red_velvet.marvel.data.model.Comic -import com.red_velvet.marvel.data.model.Event -import com.red_velvet.marvel.data.remote.RetrofitClient import com.red_velvet.marvel.data.repository.MarvelRepository -import com.red_velvet.marvel.data.repository.MarvelRepositoryImpl +import com.red_velvet.marvel.domain.model.Character +import com.red_velvet.marvel.domain.model.Comic +import com.red_velvet.marvel.domain.model.Event import com.red_velvet.marvel.ui.base.BaseViewModel import com.red_velvet.marvel.ui.utils.SingleEvent -import com.red_velvet.marvel.ui.utils.State +import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject -class HomeViewModel : BaseViewModel(), HomeInteractionListener { - - private val repository: MarvelRepository by lazy { - MarvelRepositoryImpl(RetrofitClient.apiService) - } +@HiltViewModel +class HomeViewModel @Inject constructor( + private val repository: MarvelRepository, +) : BaseViewModel(), HomeInteractionListener { private val _navigationToComicDetails: MutableLiveData> = MutableLiveData() val navigationToComicDetails: LiveData> = _navigationToComicDetails @@ -27,69 +25,63 @@ class HomeViewModel : BaseViewModel(), HomeInteractionListener { private val _navigationToCharacterDetails: MutableLiveData> = MutableLiveData() val navigationToCharacterDetails: LiveData> = _navigationToCharacterDetails - private val _comics = MutableLiveData>>(State.Loading) - val comicsLiveData: LiveData>> = _comics + private val _comics = MutableLiveData>() + val comicsLiveData: LiveData> = _comics - private val _events = MutableLiveData>>(State.Loading) - val eventLiveData: LiveData>> = _events - - private val _characters = MutableLiveData>>(State.Loading) - val characterLiveData: LiveData>> = _characters + private val _events = MutableLiveData>() + val eventLiveData: LiveData> = _events + private val _characters = MutableLiveData>() + val characterLiveData: LiveData> = _characters init { + repository.refreshComics().subscribe() + repository.refreshEvents().subscribe() + repository.refreshCharacters().subscribe() getComics() getEvents() getCharacters() } - fun getComics() { - bindStateUpdates( - repository.getAllComics(), - onError = ::onGetComicsFailure, - onNext = ::onGetComicsState + private fun getComics() { + bindObservable( + repository.getLocalComics(), + ::onComicsError, + ::onComicsReceived, ) } - private fun onGetComicsFailure(throwable: Throwable) { - _comics.postValue(State.Failed(throwable.message ?: UNKNOWN_ERROR)) - } + private fun onComicsReceived(comics: List) = _comics.postValue(comics) - private fun onGetComicsState(state: State>) { - _comics.postValue(state) - } + private fun onComicsError(throwable: Throwable) = _comics.postValue(emptyList()) - fun getEvents() { - bindStateUpdates( - repository.getAllEvents(), - onError = ::onGetEventsFailure, - onNext = ::onGetEventsState + private fun getEvents() { + bindObservable( + repository.getLocalEvents(), + ::onEventsError, + ::onEventsReceived, ) } - private fun onGetEventsFailure(throwable: Throwable) { - _events.postValue(State.Failed(throwable.message ?: UNKNOWN_ERROR)) - } + private fun onEventsReceived(events: List) = _events.postValue(events) - private fun onGetEventsState(state: State>) { - _events.postValue(state) - } + private fun onEventsError(throwable: Throwable) = _events.postValue(emptyList()) - fun getCharacters() { - bindStateUpdates( - repository.getAllCharacters(), - onError = ::onGetCharactersFailure, - onNext = ::onGetCharactersState + + private fun getCharacters() { + bindObservable( + repository.getLocalCharacters(), + ::onCharactersError, + ::onCharactersReceived, ) } - private fun onGetCharactersFailure(throwable: Throwable) { - _characters.postValue(State.Failed(throwable.message ?: UNKNOWN_ERROR)) - } + private fun onCharactersReceived(characters: List) = + _characters.postValue(characters) + + + private fun onCharactersError(throwable: Throwable) = _characters.postValue(emptyList()) - private fun onGetCharactersState(state: State>) { - _characters.postValue(state) - } override fun doOnComicClicked(comicId: Int) { _navigationToComicDetails.postValue(SingleEvent(comicId)) @@ -102,8 +94,4 @@ class HomeViewModel : BaseViewModel(), HomeInteractionListener { override fun doOnCharacterClicked(charId: Int) { _navigationToCharacterDetails.postValue(SingleEvent(charId)) } - - companion object { - private const val UNKNOWN_ERROR = "Unknown error" - } } \ No newline at end of file diff --git a/app/src/main/java/com/red_velvet/marvel/ui/home/adapter/CharactersAdapter.kt b/app/src/main/java/com/red_velvet/marvel/ui/home/adapter/CharactersAdapter.kt index 87d722b2..3c13cc67 100644 --- a/app/src/main/java/com/red_velvet/marvel/ui/home/adapter/CharactersAdapter.kt +++ b/app/src/main/java/com/red_velvet/marvel/ui/home/adapter/CharactersAdapter.kt @@ -1,7 +1,7 @@ package com.red_velvet.marvel.ui.home.adapter import com.red_velvet.marvel.R -import com.red_velvet.marvel.data.model.Character +import com.red_velvet.marvel.domain.model.Character import com.red_velvet.marvel.ui.base.BaseAdapter import com.red_velvet.marvel.ui.home.HomeInteractionListener diff --git a/app/src/main/java/com/red_velvet/marvel/ui/home/adapter/ComicsAdapter.kt b/app/src/main/java/com/red_velvet/marvel/ui/home/adapter/ComicsAdapter.kt index e420717d..c0d4cda5 100644 --- a/app/src/main/java/com/red_velvet/marvel/ui/home/adapter/ComicsAdapter.kt +++ b/app/src/main/java/com/red_velvet/marvel/ui/home/adapter/ComicsAdapter.kt @@ -1,7 +1,7 @@ package com.red_velvet.marvel.ui.home.adapter import com.red_velvet.marvel.R -import com.red_velvet.marvel.data.model.Comic +import com.red_velvet.marvel.domain.model.Comic import com.red_velvet.marvel.ui.base.BaseAdapter import com.red_velvet.marvel.ui.home.HomeInteractionListener diff --git a/app/src/main/java/com/red_velvet/marvel/ui/home/adapter/EventsAdapter.kt b/app/src/main/java/com/red_velvet/marvel/ui/home/adapter/EventsAdapter.kt index c19f884d..d02af2ba 100644 --- a/app/src/main/java/com/red_velvet/marvel/ui/home/adapter/EventsAdapter.kt +++ b/app/src/main/java/com/red_velvet/marvel/ui/home/adapter/EventsAdapter.kt @@ -1,7 +1,7 @@ package com.red_velvet.marvel.ui.home.adapter import com.red_velvet.marvel.R -import com.red_velvet.marvel.data.model.Event +import com.red_velvet.marvel.domain.model.Event import com.red_velvet.marvel.ui.base.BaseAdapter import com.red_velvet.marvel.ui.home.HomeInteractionListener diff --git a/app/src/main/java/com/red_velvet/marvel/ui/series/SeriesAdapter.kt b/app/src/main/java/com/red_velvet/marvel/ui/series/SeriesAdapter.kt index a588b0e9..566d2cae 100644 --- a/app/src/main/java/com/red_velvet/marvel/ui/series/SeriesAdapter.kt +++ b/app/src/main/java/com/red_velvet/marvel/ui/series/SeriesAdapter.kt @@ -1,12 +1,12 @@ package com.red_velvet.marvel.ui.series import com.red_velvet.marvel.R -import com.red_velvet.marvel.data.model.Series +import com.red_velvet.marvel.data.remote.dto.SeriesDto import com.red_velvet.marvel.ui.base.BaseAdapter import com.red_velvet.marvel.ui.base.BaseInteractionListener -class SeriesAdapter(items: List, listener: SeriesInteractionListener) : - BaseAdapter(items, listener) { +class SeriesAdapter(items: List, listener: SeriesInteractionListener) : + BaseAdapter(items, listener) { override val layoutId: Int = R.layout.item_series } diff --git a/app/src/main/java/com/red_velvet/marvel/ui/series/SeriesFragment.kt b/app/src/main/java/com/red_velvet/marvel/ui/series/SeriesFragment.kt index 64f55550..27a5b437 100644 --- a/app/src/main/java/com/red_velvet/marvel/ui/series/SeriesFragment.kt +++ b/app/src/main/java/com/red_velvet/marvel/ui/series/SeriesFragment.kt @@ -7,7 +7,9 @@ import androidx.navigation.fragment.findNavController import com.red_velvet.marvel.R import com.red_velvet.marvel.databinding.FragmentSeriesBinding import com.red_velvet.marvel.ui.base.BaseFragment +import dagger.hilt.android.AndroidEntryPoint +@AndroidEntryPoint class SeriesFragment : BaseFragment() { override val layoutIdFragment = R.layout.fragment_series diff --git a/app/src/main/java/com/red_velvet/marvel/ui/series/SeriesViewModel.kt b/app/src/main/java/com/red_velvet/marvel/ui/series/SeriesViewModel.kt index ef46cfdc..5619c011 100644 --- a/app/src/main/java/com/red_velvet/marvel/ui/series/SeriesViewModel.kt +++ b/app/src/main/java/com/red_velvet/marvel/ui/series/SeriesViewModel.kt @@ -3,27 +3,28 @@ package com.red_velvet.marvel.ui.series import android.util.Log import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData -import com.red_velvet.marvel.data.model.Series -import com.red_velvet.marvel.data.remote.RetrofitClient +import com.red_velvet.marvel.data.remote.dto.SeriesDto import com.red_velvet.marvel.data.repository.MarvelRepository -import com.red_velvet.marvel.data.repository.MarvelRepositoryImpl import com.red_velvet.marvel.ui.base.BaseViewModel import com.red_velvet.marvel.ui.utils.SingleEvent import com.red_velvet.marvel.ui.utils.State +import dagger.hilt.android.lifecycle.HiltViewModel import io.reactivex.rxjava3.core.Observable import io.reactivex.rxjava3.kotlin.addTo import java.util.concurrent.TimeUnit +import javax.inject.Inject -class SeriesViewModel : BaseViewModel(), SeriesInteractionListener { +@HiltViewModel +class SeriesViewModel @Inject constructor( + private val repository: MarvelRepository +) : BaseViewModel(), SeriesInteractionListener { private val _navigationToSeriesDetails: MutableLiveData> = MutableLiveData() val navigationToSeriesDetails: LiveData> = _navigationToSeriesDetails - private val _series: MutableLiveData>> = MutableLiveData() - val series: LiveData>> = _series - - val repository: MarvelRepository by lazy { MarvelRepositoryImpl(RetrofitClient.apiService) } + private val _series: MutableLiveData>> = MutableLiveData() + val series: LiveData>> = _series val searchQuery = MutableLiveData() @@ -44,7 +45,7 @@ class SeriesViewModel : BaseViewModel(), SeriesInteractionListener { _series.postValue(State.Failed(error.message.toString())) } - private fun onGetSeriesState(state: State>) { + private fun onGetSeriesState(state: State>) { _series.postValue(state) } diff --git a/app/src/main/java/com/red_velvet/marvel/ui/seriesDetails/CreatorsAdapter.kt b/app/src/main/java/com/red_velvet/marvel/ui/seriesDetails/CreatorsAdapter.kt index 5712efae..dae3cb13 100644 --- a/app/src/main/java/com/red_velvet/marvel/ui/seriesDetails/CreatorsAdapter.kt +++ b/app/src/main/java/com/red_velvet/marvel/ui/seriesDetails/CreatorsAdapter.kt @@ -1,14 +1,14 @@ package com.red_velvet.marvel.ui.seriesDetails import com.red_velvet.marvel.R -import com.red_velvet.marvel.data.model.Creator +import com.red_velvet.marvel.data.remote.dto.CreatorDto import com.red_velvet.marvel.ui.base.BaseAdapter import com.red_velvet.marvel.ui.base.BaseInteractionListener class CreatorsAdapter( - items: List, + items: List, listener: CreatorListenerInteraction, -) : BaseAdapter(items, listener) { +) : BaseAdapter(items, listener) { override val layoutId: Int = R.layout.item_creator } diff --git a/app/src/main/java/com/red_velvet/marvel/ui/seriesDetails/SeriesDetailsFragment.kt b/app/src/main/java/com/red_velvet/marvel/ui/seriesDetails/SeriesDetailsFragment.kt index ac4f434a..9bc2f046 100644 --- a/app/src/main/java/com/red_velvet/marvel/ui/seriesDetails/SeriesDetailsFragment.kt +++ b/app/src/main/java/com/red_velvet/marvel/ui/seriesDetails/SeriesDetailsFragment.kt @@ -7,7 +7,9 @@ import androidx.navigation.fragment.navArgs import com.red_velvet.marvel.R import com.red_velvet.marvel.databinding.FragmentSeriesDetailsBinding import com.red_velvet.marvel.ui.base.BaseFragment +import dagger.hilt.android.AndroidEntryPoint +@AndroidEntryPoint class SeriesDetailsFragment : BaseFragment() { override val layoutIdFragment = R.layout.fragment_series_details diff --git a/app/src/main/java/com/red_velvet/marvel/ui/seriesDetails/SeriesDetailsViewModel.kt b/app/src/main/java/com/red_velvet/marvel/ui/seriesDetails/SeriesDetailsViewModel.kt index 1205b392..cfa3f6bc 100644 --- a/app/src/main/java/com/red_velvet/marvel/ui/seriesDetails/SeriesDetailsViewModel.kt +++ b/app/src/main/java/com/red_velvet/marvel/ui/seriesDetails/SeriesDetailsViewModel.kt @@ -2,23 +2,24 @@ package com.red_velvet.marvel.ui.seriesDetails import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData -import com.red_velvet.marvel.data.model.Creator -import com.red_velvet.marvel.data.model.Series -import com.red_velvet.marvel.data.remote.RetrofitClient +import com.red_velvet.marvel.data.remote.dto.CreatorDto +import com.red_velvet.marvel.data.remote.dto.SeriesDto import com.red_velvet.marvel.data.repository.MarvelRepository -import com.red_velvet.marvel.data.repository.MarvelRepositoryImpl import com.red_velvet.marvel.ui.base.BaseViewModel import com.red_velvet.marvel.ui.utils.State +import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject -class SeriesDetailsViewModel : BaseViewModel(), CreatorListenerInteraction { +@HiltViewModel +class SeriesDetailsViewModel @Inject constructor( + private val repository: MarvelRepository +) : BaseViewModel(), CreatorListenerInteraction { - private val repository: MarvelRepository = MarvelRepositoryImpl(RetrofitClient.apiService) + private val _series: MutableLiveData>> = MutableLiveData() + val series: LiveData>> = _series - private val _series: MutableLiveData>> = MutableLiveData() - val series: LiveData>> = _series - - private val _creators: MutableLiveData>> = MutableLiveData() - val creators: LiveData>> = _creators + private val _creators: MutableLiveData>> = MutableLiveData() + val creators: LiveData>> = _creators fun loadSeriesDetails(seriesId: Int) { getSeries(seriesId) @@ -41,7 +42,7 @@ class SeriesDetailsViewModel : BaseViewModel(), CreatorListenerInteraction { ) } - private fun onGetSeriesDetailsSuccess(state: State>) { + private fun onGetSeriesDetailsSuccess(state: State>) { _series.postValue(state) } @@ -49,7 +50,7 @@ class SeriesDetailsViewModel : BaseViewModel(), CreatorListenerInteraction { _series.postValue(State.Failed(error.message.toString())) } - private fun onGetCreatorsBySeriesIdSuccess(state: State>) { + private fun onGetCreatorsBySeriesIdSuccess(state: State>) { _creators.postValue(state) } diff --git a/app/src/main/java/com/red_velvet/marvel/ui/stories/StoriesAdapter.kt b/app/src/main/java/com/red_velvet/marvel/ui/stories/StoriesAdapter.kt index 5d5de2a4..2696e5ae 100644 --- a/app/src/main/java/com/red_velvet/marvel/ui/stories/StoriesAdapter.kt +++ b/app/src/main/java/com/red_velvet/marvel/ui/stories/StoriesAdapter.kt @@ -2,12 +2,12 @@ package com.red_velvet.marvel.ui.stories import com.red_velvet.marvel.R -import com.red_velvet.marvel.data.model.Story +import com.red_velvet.marvel.data.remote.dto.StoryDto import com.red_velvet.marvel.ui.base.BaseAdapter import com.red_velvet.marvel.ui.base.BaseInteractionListener -class StoriesAdapter(stories: List, listener: StoriesInteractionListener) : - BaseAdapter(stories, listener) { +class StoriesAdapter(stories: List, listener: StoriesInteractionListener) : + BaseAdapter(stories, listener) { override val layoutId = R.layout.item_stories } diff --git a/app/src/main/java/com/red_velvet/marvel/ui/stories/StoriesFragment.kt b/app/src/main/java/com/red_velvet/marvel/ui/stories/StoriesFragment.kt index 4a8d5061..d74bd5e7 100644 --- a/app/src/main/java/com/red_velvet/marvel/ui/stories/StoriesFragment.kt +++ b/app/src/main/java/com/red_velvet/marvel/ui/stories/StoriesFragment.kt @@ -7,7 +7,9 @@ import androidx.navigation.fragment.findNavController import com.red_velvet.marvel.R import com.red_velvet.marvel.databinding.FragmentStoriesBinding import com.red_velvet.marvel.ui.base.BaseFragment +import dagger.hilt.android.AndroidEntryPoint +@AndroidEntryPoint class StoriesFragment : BaseFragment() { override val layoutIdFragment = R.layout.fragment_stories diff --git a/app/src/main/java/com/red_velvet/marvel/ui/stories/StoriesViewModel.kt b/app/src/main/java/com/red_velvet/marvel/ui/stories/StoriesViewModel.kt index 7655a8e9..b18a3ba8 100644 --- a/app/src/main/java/com/red_velvet/marvel/ui/stories/StoriesViewModel.kt +++ b/app/src/main/java/com/red_velvet/marvel/ui/stories/StoriesViewModel.kt @@ -2,23 +2,25 @@ package com.red_velvet.marvel.ui.stories import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData -import com.red_velvet.marvel.data.model.Story -import com.red_velvet.marvel.data.remote.RetrofitClient -import com.red_velvet.marvel.data.repository.MarvelRepositoryImpl +import com.red_velvet.marvel.data.remote.dto.StoryDto +import com.red_velvet.marvel.data.repository.MarvelRepository import com.red_velvet.marvel.ui.base.BaseViewModel import com.red_velvet.marvel.ui.utils.SingleEvent import com.red_velvet.marvel.ui.utils.State +import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject -class StoriesViewModel : BaseViewModel(), StoriesInteractionListener { - - private val repository by lazy { MarvelRepositoryImpl(RetrofitClient.apiService) } +@HiltViewModel +class StoriesViewModel @Inject constructor( + private val repository: MarvelRepository +) : BaseViewModel(), StoriesInteractionListener { private val _navigationToStoryDetails: MutableLiveData> = MutableLiveData() val navigationToStoryDetails: LiveData> = _navigationToStoryDetails - private val _stories: MutableLiveData>> = MutableLiveData() - val stories: LiveData>> = _stories + private val _stories: MutableLiveData>> = MutableLiveData() + val stories: LiveData>> = _stories init { getAllStories() @@ -32,7 +34,7 @@ class StoriesViewModel : BaseViewModel(), StoriesInteractionListener { ) } - private fun onGetStoriesState(state: State>) { + private fun onGetStoriesState(state: State>) { _stories.postValue(state) } diff --git a/app/src/main/java/com/red_velvet/marvel/ui/storyDetails/StoryCreatorAdapter.kt b/app/src/main/java/com/red_velvet/marvel/ui/storyDetails/StoryCreatorAdapter.kt index f3e1d4e9..d0ea3303 100644 --- a/app/src/main/java/com/red_velvet/marvel/ui/storyDetails/StoryCreatorAdapter.kt +++ b/app/src/main/java/com/red_velvet/marvel/ui/storyDetails/StoryCreatorAdapter.kt @@ -1,15 +1,15 @@ package com.red_velvet.marvel.ui.storyDetails import com.red_velvet.marvel.R -import com.red_velvet.marvel.data.model.Creator +import com.red_velvet.marvel.data.remote.dto.CreatorDto import com.red_velvet.marvel.ui.base.BaseAdapter import com.red_velvet.marvel.ui.base.BaseInteractionListener class StoryCreatorAdapter( - items: List, + items: List, listener: StoryCreatorInteractionListener ) : - BaseAdapter(items, listener) { + BaseAdapter(items, listener) { override val layoutId: Int = R.layout.item_story_creator } diff --git a/app/src/main/java/com/red_velvet/marvel/ui/storyDetails/StoryDetailsFragment.kt b/app/src/main/java/com/red_velvet/marvel/ui/storyDetails/StoryDetailsFragment.kt index 96658c34..b3f1460d 100644 --- a/app/src/main/java/com/red_velvet/marvel/ui/storyDetails/StoryDetailsFragment.kt +++ b/app/src/main/java/com/red_velvet/marvel/ui/storyDetails/StoryDetailsFragment.kt @@ -7,8 +7,9 @@ import androidx.navigation.fragment.navArgs import com.red_velvet.marvel.R import com.red_velvet.marvel.databinding.FragmentStoryBinding import com.red_velvet.marvel.ui.base.BaseFragment +import dagger.hilt.android.AndroidEntryPoint - +@AndroidEntryPoint class StoryDetailsFragment : BaseFragment() { override val layoutIdFragment: Int = R.layout.fragment_story diff --git a/app/src/main/java/com/red_velvet/marvel/ui/storyDetails/StoryDetailsViewModel.kt b/app/src/main/java/com/red_velvet/marvel/ui/storyDetails/StoryDetailsViewModel.kt index 6040a61e..66f42c05 100644 --- a/app/src/main/java/com/red_velvet/marvel/ui/storyDetails/StoryDetailsViewModel.kt +++ b/app/src/main/java/com/red_velvet/marvel/ui/storyDetails/StoryDetailsViewModel.kt @@ -2,29 +2,28 @@ package com.red_velvet.marvel.ui.storyDetails import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData -import com.red_velvet.marvel.data.model.Comic -import com.red_velvet.marvel.data.model.Creator -import com.red_velvet.marvel.data.model.Story -import com.red_velvet.marvel.data.remote.RetrofitClient +import com.red_velvet.marvel.data.remote.dto.ComicDto +import com.red_velvet.marvel.data.remote.dto.CreatorDto +import com.red_velvet.marvel.data.remote.dto.StoryDto import com.red_velvet.marvel.data.repository.MarvelRepository -import com.red_velvet.marvel.data.repository.MarvelRepositoryImpl import com.red_velvet.marvel.ui.base.BaseViewModel import com.red_velvet.marvel.ui.utils.State +import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject -class StoryDetailsViewModel : BaseViewModel(), StoryCreatorInteractionListener { +@HiltViewModel +class StoryDetailsViewModel @Inject constructor( + private val repository: MarvelRepository +) : BaseViewModel(), StoryCreatorInteractionListener { - private val _story: MutableLiveData>> = MutableLiveData() - val story: LiveData>> = _story + private val _story: MutableLiveData>> = MutableLiveData() + val story: LiveData>> = _story - private val _comics: MutableLiveData>> = MutableLiveData() - val comics: LiveData>> = _comics + private val _comics: MutableLiveData>> = MutableLiveData() + val comics: LiveData>> = _comics - private val _creators: MutableLiveData>> = MutableLiveData() - val creators: LiveData>> = _creators - - private val repository: MarvelRepository by lazy { - MarvelRepositoryImpl(RetrofitClient.apiService) - } + private val _creators: MutableLiveData>> = MutableLiveData() + val creators: LiveData>> = _creators fun loadStoryDetails(storyId: Int) { getStoryById(storyId) @@ -60,7 +59,7 @@ class StoryDetailsViewModel : BaseViewModel(), StoryCreatorInteractionListener { _creators.postValue(State.Failed(error.message.toString())) } - private fun onGetCreatorState(state: State>) { + private fun onGetCreatorState(state: State>) { _creators.postValue(state) } @@ -68,7 +67,7 @@ class StoryDetailsViewModel : BaseViewModel(), StoryCreatorInteractionListener { _comics.postValue(State.Failed(error.message.toString())) } - private fun onGetComicsState(state: State>) { + private fun onGetComicsState(state: State>) { _comics.postValue(state) } @@ -76,7 +75,7 @@ class StoryDetailsViewModel : BaseViewModel(), StoryCreatorInteractionListener { _story.postValue(State.Failed(error.message.toString())) } - private fun onGetStoryState(state: State>) { + private fun onGetStoryState(state: State>) { _story.postValue(state) } diff --git a/app/src/main/java/com/red_velvet/marvel/ui/utils/BindingAdapters.kt b/app/src/main/java/com/red_velvet/marvel/ui/utils/BindingAdapters.kt index 38711f15..8483eb59 100644 --- a/app/src/main/java/com/red_velvet/marvel/ui/utils/BindingAdapters.kt +++ b/app/src/main/java/com/red_velvet/marvel/ui/utils/BindingAdapters.kt @@ -6,7 +6,8 @@ import androidx.databinding.BindingAdapter import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.Glide import com.red_velvet.marvel.R -import com.red_velvet.marvel.data.model.Thumbnail +import com.red_velvet.marvel.data.remote.dto.ThumbnailDto +import com.red_velvet.marvel.domain.util.toUrl import com.red_velvet.marvel.ui.base.BaseAdapter @BindingAdapter(value = ["app:showWhenLoading"]) @@ -37,7 +38,7 @@ fun showWhenSuccess(view: View, state: State?) { } @BindingAdapter(value = ["app:imageUrl"]) -fun loadImage(view: ImageView, thumbnail: Thumbnail?) { +fun loadImage(view: ImageView, thumbnail: ThumbnailDto?) { Glide.with(view).load(thumbnail?.toUrl()) .thumbnail(Glide.with(view).load(R.raw.loading)) .fitCenter() @@ -45,6 +46,15 @@ fun loadImage(view: ImageView, thumbnail: Thumbnail?) { .into(view) } +@BindingAdapter(value = ["app:imageUrl"]) +fun loadImage(view: ImageView, imageUrl: String?) { + Glide.with(view).load(imageUrl) + .thumbnail(Glide.with(view).load(R.raw.loading)) + .fitCenter() + .centerCrop() + .into(view) +} + @BindingAdapter(value = ["app:setItems"]) fun setRecyclerItems(view: RecyclerView, items: List?) { if (items != null) { diff --git a/app/src/main/java/com/red_velvet/marvel/ui/utils/extensions.kt b/app/src/main/java/com/red_velvet/marvel/ui/utils/extensions.kt index dfbff96d..a14643b7 100644 --- a/app/src/main/java/com/red_velvet/marvel/ui/utils/extensions.kt +++ b/app/src/main/java/com/red_velvet/marvel/ui/utils/extensions.kt @@ -1,9 +1,6 @@ package com.red_velvet.marvel.ui.utils import android.view.View -import com.red_velvet.marvel.data.model.Thumbnail - -fun Thumbnail.toUrl() = this.path + "." + this.extension fun View.hideView() { visibility = View.GONE diff --git a/app/src/main/res/layout/characters_item.xml b/app/src/main/res/layout/characters_item.xml index 1f71195a..0f1b1723 100644 --- a/app/src/main/res/layout/characters_item.xml +++ b/app/src/main/res/layout/characters_item.xml @@ -6,7 +6,7 @@ + type="com.red_velvet.marvel.data.remote.dto.CharacterDto" /> diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml index 79d2885e..98c8b341 100644 --- a/app/src/main/res/layout/fragment_home.xml +++ b/app/src/main/res/layout/fragment_home.xml @@ -35,7 +35,7 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" - app:showWhenSuccess="@{viewModel.comicsLiveData}" /> + app:showWhenData="@{viewModel.comicsLiveData.empty}" /> + app:showWhenData="@{viewModel.eventLiveData.empty}" /> + app:layout_constraintTop_toBottomOf="@id/recycler_events" + app:showWhenData="@{viewModel.characterLiveData.empty}" /> - - - + app:lottie_autoPlay="true" + app:lottie_loop="true" + app:lottie_rawRes="@raw/search_empty" + app:showWhenData="@{!viewModel.comicsLiveData.empty}" /> + android:gravity="center" + android:padding="@dimen/padding_normal" + android:text="@string/no_data" + android:textColor="@color/tertiary_87" + android:textSize="@dimen/font_size_body" + app:layout_constraintEnd_toEndOf="@id/animation_view_search_empty" + app:layout_constraintStart_toStartOf="@id/animation_view_search_empty" + app:layout_constraintTop_toBottomOf="@id/animation_view_search_empty" + app:showWhenData="@{!viewModel.comicsLiveData.empty}" /> diff --git a/app/src/main/res/layout/item_character_comics.xml b/app/src/main/res/layout/item_character_comics.xml index da01aee2..4bc27b9a 100644 --- a/app/src/main/res/layout/item_character_comics.xml +++ b/app/src/main/res/layout/item_character_comics.xml @@ -7,7 +7,7 @@ + type="com.red_velvet.marvel.data.remote.dto.ComicDto" /> + type="com.red_velvet.marvel.data.remote.dto.SeriesDto" /> + type="com.red_velvet.marvel.data.remote.dto.CharacterDto" /> + type="com.red_velvet.marvel.data.remote.dto.CharacterDto" /> diff --git a/app/src/main/res/layout/item_comic_creator.xml b/app/src/main/res/layout/item_comic_creator.xml index 9a7a4c7c..fbe1c804 100644 --- a/app/src/main/res/layout/item_comic_creator.xml +++ b/app/src/main/res/layout/item_comic_creator.xml @@ -1,13 +1,12 @@ + xmlns:app="http://schemas.android.com/apk/res-auto"> + type="com.red_velvet.marvel.data.remote.dto.CreatorDto" /> + type="com.red_velvet.marvel.data.remote.dto.CreatorDto" /> + xmlns:app="http://schemas.android.com/apk/res-auto"> + type="com.red_velvet.marvel.data.remote.dto.CreatorDto" /> diff --git a/app/src/main/res/layout/item_event.xml b/app/src/main/res/layout/item_event.xml index 4a4a25f9..d5bb4df0 100644 --- a/app/src/main/res/layout/item_event.xml +++ b/app/src/main/res/layout/item_event.xml @@ -6,7 +6,7 @@ + type="com.red_velvet.marvel.data.remote.dto.EventDto" /> diff --git a/app/src/main/res/layout/item_home_character.xml b/app/src/main/res/layout/item_home_character.xml index 7e6ae166..714e2971 100644 --- a/app/src/main/res/layout/item_home_character.xml +++ b/app/src/main/res/layout/item_home_character.xml @@ -7,7 +7,7 @@ + type="com.red_velvet.marvel.domain.model.Character" /> + type="com.red_velvet.marvel.domain.model.Comic" /> + type="com.red_velvet.marvel.domain.model.Event" /> + type="com.red_velvet.marvel.data.remote.dto.SeriesDto" /> + type="com.red_velvet.marvel.data.remote.dto.StoryDto" /> + type="com.red_velvet.marvel.data.remote.dto.CreatorDto" /> Search Looks like Thanos snapped this search result away. \nTry searching for something else. Home + There is no data to show\nplease make sure you are connected to the internet and try again. \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 5c58a33b..c27a1c6d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,6 +3,7 @@ plugins { id("com.android.application") version "8.0.0" apply false id("com.android.library") version "8.0.0" apply false id("org.jetbrains.kotlin.android") version "1.8.0" apply false + id("com.google.dagger.hilt.android") version "2.44" apply false } buildscript { repositories {