diff --git a/buildSrc/src/main/java/Dependencies.kt b/buildSrc/src/main/java/Dependencies.kt index 64f4bbe..abf0847 100644 --- a/buildSrc/src/main/java/Dependencies.kt +++ b/buildSrc/src/main/java/Dependencies.kt @@ -29,6 +29,7 @@ object Versions { internal const val fabricTools = "1.31.2" internal const val materialVersion = "1.0.0" internal const val cardView = "28.0.0" + internal const val roomVersion = "2.2.3" } object GradleDependencies { @@ -73,4 +74,6 @@ object LibsDependencies { const val glide = "com.github.bumptech.glide:glide:${Versions.glide}" const val glideAnnotation = "com.github.bumptech.glide:compiler:${Versions.glide}" const val httpLoggingInterceptor = "com.squareup.okhttp3:logging-interceptor:${Versions.httpLoggingInterceptorVersion}" + const val room = "androidx.room:room-runtime:${Versions.roomVersion}" + const val roomCompiler = "androidx.room:room-compiler:${Versions.roomVersion}" } diff --git a/data/build.gradle b/data/build.gradle index a77224b..44c384d 100644 --- a/data/build.gradle +++ b/data/build.gradle @@ -1,6 +1,7 @@ apply plugin: 'com.android.library' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' +apply plugin: 'kotlin-kapt' apply from: "$rootDir/detekt.gradle" def apiPropertiesFile = rootProject.file("api.properties") @@ -20,6 +21,12 @@ android { buildConfigField("String", "MARVEL_PRIVATE_KEY", apiProperties['MARVEL_PRIVATE_KEY']) buildConfigField("String", "MARVEL_PUBLIC_KEY", apiProperties['MARVEL_PUBLIC_KEY']) buildConfigField("String", "TIME_STAMP", apiProperties['TIME_STAMP']) + + javaCompileOptions { + annotationProcessorOptions { + arguments = ["room.incremental":"true"] + } + } } buildTypes { @@ -39,6 +46,9 @@ dependencies { implementation SupportDependencies.appCompat implementation SupportDependencies.coreKtx + implementation LibsDependencies.room + kapt LibsDependencies.roomCompiler + api LibsDependencies.retrofit2 api LibsDependencies.retrofitGson api LibsDependencies.httpLoggingInterceptor @@ -46,6 +56,7 @@ dependencies { testImplementation TestDependencies.junit testImplementation TestDependencies.robolectric testImplementation TestDependencies.coroutinesTest + androidTestImplementation TestDependencies.testJunit androidTestImplementation TestDependencies.espressoCore } \ No newline at end of file diff --git a/data/src/main/java/com/architect/coders/mu8/data/DataApp.kt b/data/src/main/java/com/architect/coders/mu8/data/DataApp.kt new file mode 100644 index 0000000..3928583 --- /dev/null +++ b/data/src/main/java/com/architect/coders/mu8/data/DataApp.kt @@ -0,0 +1,20 @@ +package com.architect.coders.mu8.data + +import android.app.Application +import androidx.room.Room +import com.architect.coders.mu8.data.database.MU8Database + +open class DataApp : Application() { + + lateinit var database: MU8Database + private set + + override fun onCreate() { + super.onCreate() + database = Room.databaseBuilder( + this, + MU8Database::class.java, + "MU8-db" + ).build() + } +} \ No newline at end of file diff --git a/data/src/main/java/com/architect/coders/mu8/data/local/categories/CategoriesRepository.kt b/data/src/main/java/com/architect/coders/mu8/data/categories/CategoriesRepository.kt similarity index 76% rename from data/src/main/java/com/architect/coders/mu8/data/local/categories/CategoriesRepository.kt rename to data/src/main/java/com/architect/coders/mu8/data/categories/CategoriesRepository.kt index 3152e8d..5845c03 100644 --- a/data/src/main/java/com/architect/coders/mu8/data/local/categories/CategoriesRepository.kt +++ b/data/src/main/java/com/architect/coders/mu8/data/categories/CategoriesRepository.kt @@ -1,8 +1,8 @@ -package com.architect.coders.mu8.data.local.categories +package com.architect.coders.mu8.data.categories -import com.architect.codes.mu8.CHARACTERS -import com.architect.codes.mu8.COMICS -import com.architect.codes.mu8.EVENTS +import com.architect.codes.mu8.utils.CHARACTERS +import com.architect.codes.mu8.utils.COMICS +import com.architect.codes.mu8.utils.EVENTS import com.architect.codes.mu8.categories.Category class CategoriesRepository { diff --git a/data/src/main/java/com/architect/coders/mu8/data/characters/CharactersDAO.kt b/data/src/main/java/com/architect/coders/mu8/data/characters/CharactersDAO.kt new file mode 100644 index 0000000..16bdd3b --- /dev/null +++ b/data/src/main/java/com/architect/coders/mu8/data/characters/CharactersDAO.kt @@ -0,0 +1,19 @@ +package com.architect.coders.mu8.data.characters + +import androidx.room.Dao +import androidx.room.Insert +import androidx.room.OnConflictStrategy.IGNORE +import androidx.room.Query + +@Dao +interface CharactersDAO { + + @Query("SELECT * FROM CharactersEntity") + fun getAllCharacters(): List + + @Query("SELECT COUNT(id) FROM CharactersEntity") + fun charactersCount(): Int + + @Insert(onConflict = IGNORE) + fun insertCharacters(characters: List) +} \ No newline at end of file diff --git a/data/src/main/java/com/architect/coders/mu8/data/characters/CharactersEntity.kt b/data/src/main/java/com/architect/coders/mu8/data/characters/CharactersEntity.kt new file mode 100644 index 0000000..0b4148c --- /dev/null +++ b/data/src/main/java/com/architect/coders/mu8/data/characters/CharactersEntity.kt @@ -0,0 +1,16 @@ +package com.architect.coders.mu8.data.characters + +import androidx.room.Entity +import androidx.room.PrimaryKey +import com.architect.coders.mu8.data.response.common.ThumbnailEntity +import com.architect.coders.mu8.data.response.common.UrlsEntity +import com.architect.codes.mu8.utils.EMPTY_STRING + +@Entity +data class CharactersEntity( + @PrimaryKey(autoGenerate = false) val id: Long = 0L, + val name: String = EMPTY_STRING, + val description: String = EMPTY_STRING, + val thumbnail: ThumbnailEntity, + val urls: List +) \ No newline at end of file diff --git a/data/src/main/java/com/architect/coders/mu8/data/characters/CharactersMapper.kt b/data/src/main/java/com/architect/coders/mu8/data/characters/CharactersMapper.kt index beb1264..9593d4d 100644 --- a/data/src/main/java/com/architect/coders/mu8/data/characters/CharactersMapper.kt +++ b/data/src/main/java/com/architect/coders/mu8/data/characters/CharactersMapper.kt @@ -5,9 +5,11 @@ import com.architect.coders.mu8.data.mapper.common.UrlsMapper import com.architect.coders.mu8.data.utils.replaceHttps import com.architect.codes.mu8.characters.Character -class CharactersMapper(private val urlsMapper: UrlsMapper) : BaseResponseMapper() { +class CharactersMapper( + private val urlsMapper: UrlsMapper +) : BaseResponseMapper() { - override fun transform(input: CharactersResponse): Character { + override fun transform(input: CharactersEntity): Character { return Character( input.id, input.name, diff --git a/data/src/main/java/com/architect/coders/mu8/data/characters/CharactersRepositoryImpl.kt b/data/src/main/java/com/architect/coders/mu8/data/characters/CharactersRepositoryImpl.kt index dc3e83d..dac643b 100644 --- a/data/src/main/java/com/architect/coders/mu8/data/characters/CharactersRepositoryImpl.kt +++ b/data/src/main/java/com/architect/coders/mu8/data/characters/CharactersRepositoryImpl.kt @@ -1,30 +1,40 @@ package com.architect.coders.mu8.data.characters -import com.architect.coders.mu8.data.service.MarvelServiceManager +import com.architect.coders.mu8.data.DataApp import com.architect.coders.mu8.data.service.MarvelServiceManager.hashcode +import com.architect.coders.mu8.data.service.MarvelServiceManager.service +import com.architect.coders.mu8.data.utils.DEFAULT_OFFSET +import com.architect.coders.mu8.data.utils.LIMIT import com.architect.coders.mu8.data.utils.MARVEL_PUBLIC_KEY import com.architect.coders.mu8.data.utils.TIME_STAMP import com.architect.codes.mu8.characters.Character import com.architect.codes.mu8.characters.CharactersRepository -import com.architect.codes.mu8.common.Scope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext class CharactersRepositoryImpl( - private val mapper: CharactersMapper -) : CharactersRepository, Scope by Scope.Implementation() { + private val mapper: CharactersMapper, + application: DataApp +) : CharactersRepository { - init { - initScope() - } + private val database = application.database - override suspend fun invoke(): List { - val response = MarvelServiceManager.service.getAllCharacters(TIME_STAMP, MARVEL_PUBLIC_KEY, hashcode) + override suspend fun invoke(): List = withContext(Dispatchers.IO) { + with(database.getCharactersDao()) { + if (charactersCount() <= 0) { + val response = service.getAllCharacters( + TIME_STAMP, + MARVEL_PUBLIC_KEY, + hashcode, + DEFAULT_OFFSET, + LIMIT + ) - val characters = mutableListOf() - if (response.isSuccessful) { - response.body()?.data?.results?.forEach { - characters.add(mapper.transform(it)) + if (response.isSuccessful) { + response.body()?.data?.results?.run { insertCharacters(this) } + } } + return@withContext getAllCharacters().map { mapper.transform(it) } } - return characters } } diff --git a/data/src/main/java/com/architect/coders/mu8/data/characters/CharactersResponse.kt b/data/src/main/java/com/architect/coders/mu8/data/characters/CharactersResponse.kt deleted file mode 100644 index a79f08e..0000000 --- a/data/src/main/java/com/architect/coders/mu8/data/characters/CharactersResponse.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.architect.coders.mu8.data.characters - -import com.architect.coders.mu8.data.response.common.ThumbnailResponse -import com.architect.coders.mu8.data.response.common.UrlsResponse -import com.architect.codes.mu8.EMPTY_STRING - -data class CharactersResponse( - val id: Long = 0L, - val name: String = EMPTY_STRING, - val description: String = EMPTY_STRING, - val thumbnail: ThumbnailResponse, - val urls: List -) \ No newline at end of file diff --git a/data/src/main/java/com/architect/coders/mu8/data/comics/model/ComicResponse.kt b/data/src/main/java/com/architect/coders/mu8/data/comics/ComicResponse.kt similarity index 67% rename from data/src/main/java/com/architect/coders/mu8/data/comics/model/ComicResponse.kt rename to data/src/main/java/com/architect/coders/mu8/data/comics/ComicResponse.kt index 4bccfa5..a05efcc 100644 --- a/data/src/main/java/com/architect/coders/mu8/data/comics/model/ComicResponse.kt +++ b/data/src/main/java/com/architect/coders/mu8/data/comics/ComicResponse.kt @@ -1,6 +1,6 @@ -package com.architect.coders.mu8.data.comics.model +package com.architect.coders.mu8.data.comics -import com.architect.coders.mu8.data.response.common.ThumbnailResponse +import com.architect.coders.mu8.data.response.common.ThumbnailEntity import com.google.gson.annotations.SerializedName data class ComicResponse( @@ -17,5 +17,5 @@ data class ComicResponse( val format: String, @SerializedName("thumbnail") - val thumbnail: ThumbnailResponse + val thumbnail: ThumbnailEntity ) diff --git a/data/src/main/java/com/architect/coders/mu8/data/comics/ComicsMapper.kt b/data/src/main/java/com/architect/coders/mu8/data/comics/ComicsMapper.kt index 6232b52..eb0a86f 100644 --- a/data/src/main/java/com/architect/coders/mu8/data/comics/ComicsMapper.kt +++ b/data/src/main/java/com/architect/coders/mu8/data/comics/ComicsMapper.kt @@ -1,6 +1,5 @@ package com.architect.coders.mu8.data.comics -import com.architect.coders.mu8.data.comics.model.ComicResponse import com.architect.coders.mu8.data.mapper.BaseResponseMapper import com.architect.coders.mu8.data.utils.replaceHttps import com.architect.codes.mu8.comics.Comic diff --git a/data/src/main/java/com/architect/coders/mu8/data/comics/model/ComicCharacterResponse.kt b/data/src/main/java/com/architect/coders/mu8/data/comics/model/ComicCharacterResponse.kt deleted file mode 100644 index 1b35789..0000000 --- a/data/src/main/java/com/architect/coders/mu8/data/comics/model/ComicCharacterResponse.kt +++ /dev/null @@ -1,3 +0,0 @@ -package com.architect.coders.mu8.data.comics.model - -data class ComicCharacterResponse(val resourceURI: String, val name: String) \ No newline at end of file diff --git a/data/src/main/java/com/architect/coders/mu8/data/database/MU8Database.kt b/data/src/main/java/com/architect/coders/mu8/data/database/MU8Database.kt new file mode 100644 index 0000000..e759c4c --- /dev/null +++ b/data/src/main/java/com/architect/coders/mu8/data/database/MU8Database.kt @@ -0,0 +1,17 @@ +package com.architect.coders.mu8.data.database + +import androidx.room.Database +import androidx.room.RoomDatabase +import androidx.room.TypeConverters +import com.architect.coders.mu8.data.characters.CharactersDAO +import com.architect.coders.mu8.data.characters.CharactersEntity +import com.architect.coders.mu8.data.database.converter.ThumbnailTypeConverters +import com.architect.coders.mu8.data.database.converter.UrlsTypeConverters + +private const val DATABASE_VERSION = 1 + +@Database(entities = [CharactersEntity::class], version = DATABASE_VERSION) +@TypeConverters(UrlsTypeConverters::class, ThumbnailTypeConverters::class) +abstract class MU8Database : RoomDatabase() { + abstract fun getCharactersDao(): CharactersDAO +} \ No newline at end of file diff --git a/data/src/main/java/com/architect/coders/mu8/data/database/converter/ThumbnailTypeConverters.kt b/data/src/main/java/com/architect/coders/mu8/data/database/converter/ThumbnailTypeConverters.kt new file mode 100644 index 0000000..bddc7da --- /dev/null +++ b/data/src/main/java/com/architect/coders/mu8/data/database/converter/ThumbnailTypeConverters.kt @@ -0,0 +1,28 @@ +package com.architect.coders.mu8.data.database.converter + +import androidx.room.TypeConverter +import com.architect.coders.mu8.data.response.common.ThumbnailEntity +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken + +class ThumbnailTypeConverters { + + private val gson = Gson() + + @TypeConverter + fun stringToThumbnail(data: String?): ThumbnailEntity { + if (data == null) { + return ThumbnailEntity() + } + val type = object : TypeToken() {}.type + return gson.fromJson(data, type) + } + + @TypeConverter + fun thumbnailToString(thumbnail: ThumbnailEntity?): String { + if (thumbnail == null) { + return gson.toJson(ThumbnailEntity()) + } + return gson.toJson(thumbnail) + } +} \ No newline at end of file diff --git a/data/src/main/java/com/architect/coders/mu8/data/database/converter/UrlsTypeConverters.kt b/data/src/main/java/com/architect/coders/mu8/data/database/converter/UrlsTypeConverters.kt new file mode 100644 index 0000000..1e97312 --- /dev/null +++ b/data/src/main/java/com/architect/coders/mu8/data/database/converter/UrlsTypeConverters.kt @@ -0,0 +1,28 @@ +package com.architect.coders.mu8.data.database.converter + +import androidx.room.TypeConverter +import com.architect.coders.mu8.data.response.common.UrlsEntity +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken + +class UrlsTypeConverters { + + private val gson = Gson() + + @TypeConverter + fun stringToUrls(data: String?): List { + if (data == null) { + return emptyList() + } + val type = object : TypeToken>() {}.type + return gson.fromJson(data, type) + } + + @TypeConverter + fun urlsToString(urls: List?): String { + if (urls.isNullOrEmpty()) { + gson.toJson(emptyList()) + } + return gson.toJson(urls) + } +} \ No newline at end of file diff --git a/data/src/main/java/com/architect/coders/mu8/data/mapper/common/UrlsMapper.kt b/data/src/main/java/com/architect/coders/mu8/data/mapper/common/UrlsMapper.kt index 394019f..204adcf 100644 --- a/data/src/main/java/com/architect/coders/mu8/data/mapper/common/UrlsMapper.kt +++ b/data/src/main/java/com/architect/coders/mu8/data/mapper/common/UrlsMapper.kt @@ -1,16 +1,16 @@ package com.architect.coders.mu8.data.mapper.common import com.architect.coders.mu8.data.mapper.BaseResponseMapper -import com.architect.coders.mu8.data.response.common.UrlsResponse +import com.architect.coders.mu8.data.response.common.UrlsEntity import com.architect.codes.mu8.common.Urls -class UrlsMapper : BaseResponseMapper() { +class UrlsMapper : BaseResponseMapper() { - override fun transform(input: UrlsResponse): Urls { + override fun transform(input: UrlsEntity): Urls { return Urls(input.type, input.url) } - fun transform(input: List): List { + fun transform(input: List): List { val output = mutableListOf() input.forEach { output.add(transform(it)) } return output diff --git a/data/src/main/java/com/architect/coders/mu8/data/response/common/ThumbnailEntity.kt b/data/src/main/java/com/architect/coders/mu8/data/response/common/ThumbnailEntity.kt new file mode 100644 index 0000000..186a99f --- /dev/null +++ b/data/src/main/java/com/architect/coders/mu8/data/response/common/ThumbnailEntity.kt @@ -0,0 +1,5 @@ +package com.architect.coders.mu8.data.response.common + +import com.architect.codes.mu8.utils.EMPTY_STRING + +data class ThumbnailEntity(val path: String = EMPTY_STRING, val extension: String = EMPTY_STRING) diff --git a/data/src/main/java/com/architect/coders/mu8/data/response/common/ThumbnailResponse.kt b/data/src/main/java/com/architect/coders/mu8/data/response/common/ThumbnailResponse.kt deleted file mode 100644 index 4732ac5..0000000 --- a/data/src/main/java/com/architect/coders/mu8/data/response/common/ThumbnailResponse.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.architect.coders.mu8.data.response.common - -import com.architect.codes.mu8.EMPTY_STRING - -data class ThumbnailResponse(val path: String = EMPTY_STRING, val extension: String = EMPTY_STRING) diff --git a/data/src/main/java/com/architect/coders/mu8/data/response/common/UrlsEntity.kt b/data/src/main/java/com/architect/coders/mu8/data/response/common/UrlsEntity.kt new file mode 100644 index 0000000..b2a016c --- /dev/null +++ b/data/src/main/java/com/architect/coders/mu8/data/response/common/UrlsEntity.kt @@ -0,0 +1,3 @@ +package com.architect.coders.mu8.data.response.common + +data class UrlsEntity(val type: String, val url: String) diff --git a/data/src/main/java/com/architect/coders/mu8/data/response/common/UrlsResponse.kt b/data/src/main/java/com/architect/coders/mu8/data/response/common/UrlsResponse.kt deleted file mode 100644 index 2191e41..0000000 --- a/data/src/main/java/com/architect/coders/mu8/data/response/common/UrlsResponse.kt +++ /dev/null @@ -1,3 +0,0 @@ -package com.architect.coders.mu8.data.response.common - -data class UrlsResponse(val type: String, val url: String) diff --git a/data/src/main/java/com/architect/coders/mu8/data/service/MarvelServiceAPI.kt b/data/src/main/java/com/architect/coders/mu8/data/service/MarvelServiceAPI.kt index f4d3d9b..61ece43 100644 --- a/data/src/main/java/com/architect/coders/mu8/data/service/MarvelServiceAPI.kt +++ b/data/src/main/java/com/architect/coders/mu8/data/service/MarvelServiceAPI.kt @@ -1,17 +1,18 @@ package com.architect.coders.mu8.data.service -import com.architect.coders.mu8.data.BuildConfig -import com.architect.coders.mu8.data.characters.CharactersResponse -import com.architect.coders.mu8.data.comics.model.ComicResponse +import com.architect.coders.mu8.data.characters.CharactersEntity +import com.architect.coders.mu8.data.comics.ComicResponse import com.architect.coders.mu8.data.response.BaseResponse -import com.architect.coders.mu8.data.service.MarvelServiceAPI.Companion.API_KEY -import com.architect.coders.mu8.data.service.MarvelServiceAPI.Companion.HASH -import com.architect.coders.mu8.data.service.MarvelServiceAPI.Companion.TIME_STAMP -import com.architect.coders.mu8.data.utils.createHashCode import retrofit2.Response import retrofit2.http.GET import retrofit2.http.Query +private const val TIME_STAMP = "ts" +private const val API_KEY = "apikey" +private const val HASH = "hash" +private const val OFFSET = "offset" +private const val LIMIT = "limit" + /** * All marvel API Calls requires {@Link [TIME_STAMP]}, {@Link[API_KEY]}, and {@Link [HASH]} */ @@ -28,12 +29,8 @@ interface MarvelServiceAPI { suspend fun getAllCharacters( @Query(TIME_STAMP) timeStamp: String, @Query(API_KEY) apiKey: String, - @Query(HASH) hash: String - ): Response> - - companion object { - private const val TIME_STAMP = "ts" - private const val API_KEY = "apikey" - private const val HASH = "hash" - } + @Query(HASH) hash: String, + @Query(OFFSET) offset: Int, + @Query(LIMIT) limit: Int + ): Response> } \ No newline at end of file diff --git a/data/src/main/java/com/architect/coders/mu8/data/utils/DataExt.kt b/data/src/main/java/com/architect/coders/mu8/data/utils/DataExtensions.kt similarity index 100% rename from data/src/main/java/com/architect/coders/mu8/data/utils/DataExt.kt rename to data/src/main/java/com/architect/coders/mu8/data/utils/DataExtensions.kt diff --git a/data/src/main/java/com/architect/coders/mu8/data/utils/Utils.kt b/data/src/main/java/com/architect/coders/mu8/data/utils/Utils.kt index 80bf7be..aaa30d4 100644 --- a/data/src/main/java/com/architect/coders/mu8/data/utils/Utils.kt +++ b/data/src/main/java/com/architect/coders/mu8/data/utils/Utils.kt @@ -2,9 +2,11 @@ package com.architect.coders.mu8.data.utils import com.architect.coders.mu8.data.BuildConfig -const val TIME_STAMP = BuildConfig.TIME_STAMP -const val MARVEL_PUBLIC_KEY = BuildConfig.MARVEL_PUBLIC_KEY -const val MARVEL_PRIVATE_KEY = BuildConfig.MARVEL_PRIVATE_KEY +internal const val TIME_STAMP = BuildConfig.TIME_STAMP +internal const val MARVEL_PUBLIC_KEY = BuildConfig.MARVEL_PUBLIC_KEY +internal const val MARVEL_PRIVATE_KEY = BuildConfig.MARVEL_PRIVATE_KEY +internal const val DEFAULT_OFFSET = 0 +internal const val LIMIT = 100 /** * Create hash required to any request to Marvel API diff --git a/domain/src/main/java/com/architect/codes/mu8/characters/CharactersUseCase.kt b/domain/src/main/java/com/architect/codes/mu8/characters/CharactersUseCase.kt index 1325674..7d8ad2f 100644 --- a/domain/src/main/java/com/architect/codes/mu8/characters/CharactersUseCase.kt +++ b/domain/src/main/java/com/architect/codes/mu8/characters/CharactersUseCase.kt @@ -1,10 +1,11 @@ package com.architect.codes.mu8.characters interface CharactersUseCase { - suspend fun getCharacters(): List + suspend operator fun invoke(): List } -class CharactersUseCaseImpl(private val charactersRepository: CharactersRepository) : - CharactersUseCase { - override suspend fun getCharacters(): List = charactersRepository() +class CharactersUseCaseImpl( + private val charactersRepository: CharactersRepository +) : CharactersUseCase { + override suspend operator fun invoke(): List = charactersRepository() } diff --git a/domain/src/main/java/com/architect/codes/mu8/Constants.kt b/domain/src/main/java/com/architect/codes/mu8/utils/Constants.kt similarity index 80% rename from domain/src/main/java/com/architect/codes/mu8/Constants.kt rename to domain/src/main/java/com/architect/codes/mu8/utils/Constants.kt index 86b952a..5d46e1d 100644 --- a/domain/src/main/java/com/architect/codes/mu8/Constants.kt +++ b/domain/src/main/java/com/architect/codes/mu8/utils/Constants.kt @@ -1,4 +1,4 @@ -package com.architect.codes.mu8 +package com.architect.codes.mu8.utils const val EMPTY_STRING = "" const val NOT_FOUND = "Not Found" diff --git a/gradle.properties b/gradle.properties index 23339e0..bb61686 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,3 +19,5 @@ android.useAndroidX=true android.enableJetifier=true # Kotlin code style for this project: "official" or "obsolete": kotlin.code.style=official +# Kapt incremental +kapt.incremental.apt=true diff --git a/presentation/src/main/AndroidManifest.xml b/presentation/src/main/AndroidManifest.xml index da49291..c35a47b 100644 --- a/presentation/src/main/AndroidManifest.xml +++ b/presentation/src/main/AndroidManifest.xml @@ -6,6 +6,7 @@ { - adapter = CategoriesAdapter(viewModel::onCategoryClicked, model.categories) - recycler.layoutManager = LinearLayoutManager(this) - recycler.adapter = adapter + adapter.categories = model.categories } is UiModel.Navigation -> { when (model.categoryName) { CHARACTERS -> startActivity {} - COMICS -> startActivity{} + COMICS -> startActivity {} EVENTS -> Toast.makeText(this, EVENTS, Toast.LENGTH_SHORT).show() else -> Toast.makeText(this, NOT_FOUND, Toast.LENGTH_SHORT).show() } diff --git a/presentation/src/main/java/com/architect/coders/mu8/categories/CategoriesAdapter.kt b/presentation/src/main/java/com/architect/coders/mu8/categories/CategoriesAdapter.kt index c40813a..4c331b1 100644 --- a/presentation/src/main/java/com/architect/coders/mu8/categories/CategoriesAdapter.kt +++ b/presentation/src/main/java/com/architect/coders/mu8/categories/CategoriesAdapter.kt @@ -9,24 +9,31 @@ import com.architect.coders.mu8.R import com.architect.coders.mu8.utils.inflate import com.architect.coders.mu8.utils.loadUrl import com.architect.codes.mu8.categories.Category +import kotlin.properties.Delegates class CategoriesAdapter( - private val listener: (Category) -> Unit, - private val listCategories: List + private val listener: (Category) -> Unit ) : RecyclerView.Adapter() { + + var categories: List by Delegates.observable( + emptyList(), + { _, _, _ -> notifyDataSetChanged() } + ) + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { return ViewHolder(parent.inflate(R.layout.card_list_marvel)) } - override fun getItemCount(): Int = listCategories.size + override fun getItemCount(): Int = categories.size override fun onBindViewHolder(holder: ViewHolder, position: Int) { - val category = listCategories[position] + val category = categories[position] holder.showData(category) holder.itemView.setOnClickListener { listener(category) } } class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + private val categoryTitle by lazy { itemView.findViewById(R.id.category_title) } private val categoryImage by lazy { itemView.findViewById(R.id.category_image) } diff --git a/presentation/src/main/java/com/architect/coders/mu8/categories/CategoriesViewModel.kt b/presentation/src/main/java/com/architect/coders/mu8/categories/CategoriesViewModel.kt index 5c0c2fa..65ff22f 100644 --- a/presentation/src/main/java/com/architect/coders/mu8/categories/CategoriesViewModel.kt +++ b/presentation/src/main/java/com/architect/coders/mu8/categories/CategoriesViewModel.kt @@ -3,7 +3,7 @@ package com.architect.coders.mu8.categories import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel -import com.architect.coders.mu8.data.local.categories.CategoriesRepository +import com.architect.coders.mu8.data.categories.CategoriesRepository import com.architect.codes.mu8.categories.Category class CategoriesViewModel(private val categoriesRepository: CategoriesRepository) : ViewModel() { diff --git a/presentation/src/main/java/com/architect/coders/mu8/characters/CharactersActivity.kt b/presentation/src/main/java/com/architect/coders/mu8/characters/CharactersActivity.kt index 4cfc95f..f8704e5 100644 --- a/presentation/src/main/java/com/architect/coders/mu8/characters/CharactersActivity.kt +++ b/presentation/src/main/java/com/architect/coders/mu8/characters/CharactersActivity.kt @@ -15,6 +15,7 @@ import com.architect.coders.mu8.characters.CharactersUiModel.Content import com.architect.coders.mu8.characters.CharactersUiModel.Loading import com.architect.coders.mu8.characters.CharactersUiModel.Navigation import com.architect.coders.mu8.characters.detail.CharactersDetailActivity +import com.architect.coders.mu8.data.DataApp import com.architect.coders.mu8.data.characters.CharactersMapper import com.architect.coders.mu8.data.characters.CharactersRepositoryImpl import com.architect.coders.mu8.data.mapper.common.UrlsMapper @@ -44,7 +45,7 @@ class CharactersActivity : AppCompatActivity() { viewModel = getViewModel { CharactersViewModel( CharactersUseCaseImpl( - CharactersRepositoryImpl(CharactersMapper(UrlsMapper())) + CharactersRepositoryImpl(CharactersMapper(UrlsMapper()), application as DataApp) ) ) } diff --git a/presentation/src/main/java/com/architect/coders/mu8/characters/CharactersViewModel.kt b/presentation/src/main/java/com/architect/coders/mu8/characters/CharactersViewModel.kt index 22a3033..82adfde 100644 --- a/presentation/src/main/java/com/architect/coders/mu8/characters/CharactersViewModel.kt +++ b/presentation/src/main/java/com/architect/coders/mu8/characters/CharactersViewModel.kt @@ -7,9 +7,7 @@ import com.architect.codes.mu8.characters.Character import com.architect.codes.mu8.characters.CharactersUseCase import kotlinx.coroutines.launch -class CharactersViewModel( - private val charactersUseCase: CharactersUseCase -) : ScopedViewModel() { +class CharactersViewModel(private val charactersUseCase: CharactersUseCase) : ScopedViewModel() { private val _model = MutableLiveData() val model: LiveData @@ -21,7 +19,7 @@ class CharactersViewModel( private fun getCharacters() { launch { _model.value = CharactersUiModel.Loading - _model.value = CharactersUiModel.Content(charactersUseCase.getCharacters()) + _model.value = CharactersUiModel.Content(charactersUseCase()) } }