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