From 30cc7231a9b660cd2ea8fba0f632f263890ad482 Mon Sep 17 00:00:00 2001 From: Carlos Martinez Date: Mon, 3 Feb 2020 15:22:17 -0300 Subject: [PATCH 1/4] create album module --- albumlist/.gitignore | 1 + albumlist/build.gradle | 6 +++++ albumlist/consumer-rules.pro | 0 albumlist/proguard-rules.pro | 21 ++++++++++++++++ .../hako/albumlist/ExampleInstrumentedTest.kt | 24 +++++++++++++++++++ albumlist/src/main/AndroidManifest.xml | 2 ++ albumlist/src/main/res/values/strings.xml | 3 +++ .../com/hako/albumlist/ExampleUnitTest.kt | 17 +++++++++++++ build.gradle | 1 - settings.gradle | 2 +- 10 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 albumlist/.gitignore create mode 100644 albumlist/build.gradle create mode 100644 albumlist/consumer-rules.pro create mode 100644 albumlist/proguard-rules.pro create mode 100644 albumlist/src/androidTest/java/com/hako/albumlist/ExampleInstrumentedTest.kt create mode 100644 albumlist/src/main/AndroidManifest.xml create mode 100644 albumlist/src/main/res/values/strings.xml create mode 100644 albumlist/src/test/java/com/hako/albumlist/ExampleUnitTest.kt diff --git a/albumlist/.gitignore b/albumlist/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/albumlist/.gitignore @@ -0,0 +1 @@ +/build diff --git a/albumlist/build.gradle b/albumlist/build.gradle new file mode 100644 index 0000000..d51b157 --- /dev/null +++ b/albumlist/build.gradle @@ -0,0 +1,6 @@ +apply plugin: 'com.android.library' +apply from: '../core.gradle' + +dependencies { + implementation project(':base') +} \ No newline at end of file diff --git a/albumlist/consumer-rules.pro b/albumlist/consumer-rules.pro new file mode 100644 index 0000000..e69de29 diff --git a/albumlist/proguard-rules.pro b/albumlist/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /dev/null +++ b/albumlist/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/albumlist/src/androidTest/java/com/hako/albumlist/ExampleInstrumentedTest.kt b/albumlist/src/androidTest/java/com/hako/albumlist/ExampleInstrumentedTest.kt new file mode 100644 index 0000000..67e39df --- /dev/null +++ b/albumlist/src/androidTest/java/com/hako/albumlist/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package com.hako.albumlist + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("com.hako.albumlist.test", appContext.packageName) + } +} diff --git a/albumlist/src/main/AndroidManifest.xml b/albumlist/src/main/AndroidManifest.xml new file mode 100644 index 0000000..2d613d8 --- /dev/null +++ b/albumlist/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + diff --git a/albumlist/src/main/res/values/strings.xml b/albumlist/src/main/res/values/strings.xml new file mode 100644 index 0000000..8e98088 --- /dev/null +++ b/albumlist/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + albumlist + diff --git a/albumlist/src/test/java/com/hako/albumlist/ExampleUnitTest.kt b/albumlist/src/test/java/com/hako/albumlist/ExampleUnitTest.kt new file mode 100644 index 0000000..b865887 --- /dev/null +++ b/albumlist/src/test/java/com/hako/albumlist/ExampleUnitTest.kt @@ -0,0 +1,17 @@ +package com.hako.albumlist + +import org.junit.Test + +import org.junit.Assert.* + +/** + * Example local unit test, which will execute on the development machine (host). + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +class ExampleUnitTest { + @Test + fun addition_isCorrect() { + assertEquals(4, 2 + 2) + } +} diff --git a/build.gradle b/build.gradle index 155de55..268dbde 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,5 @@ buildscript { apply from: 'versions.gradle' - ext.kotlin_version = deps.kotlin.version repositories { google() diff --git a/settings.gradle b/settings.gradle index 0e9eb61..1b2d3f9 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,2 @@ -include ':app', ':base', ':userlist' +include ':app', ':base', ':userlist', ':albumlist' rootProject.name='Friendlists' From 1d752803d7a053df8bbf04f6b99a30e11434ab90 Mon Sep 17 00:00:00 2001 From: Carlos Martinez Date: Mon, 3 Feb 2020 16:20:30 -0300 Subject: [PATCH 2/4] clean up userlist abstraction --- .../java/com/hako/userlist/di/UserlistModules.kt | 2 -- .../domain/datasource/UserlistDatasource.kt | 13 ------------- .../com/hako/userlist/domain/usecase/GetUsers.kt | 4 ++-- 3 files changed, 2 insertions(+), 17 deletions(-) delete mode 100644 userlist/src/main/java/com/hako/userlist/domain/datasource/UserlistDatasource.kt diff --git a/userlist/src/main/java/com/hako/userlist/di/UserlistModules.kt b/userlist/src/main/java/com/hako/userlist/di/UserlistModules.kt index a69b104..d9a58bb 100644 --- a/userlist/src/main/java/com/hako/userlist/di/UserlistModules.kt +++ b/userlist/src/main/java/com/hako/userlist/di/UserlistModules.kt @@ -1,7 +1,6 @@ package com.hako.userlist.di import com.hako.base.domain.network.RemoteClient -import com.hako.userlist.domain.datasource.UserlistDatasource import com.hako.userlist.domain.datasource.UserlistRemoteApi import com.hako.userlist.domain.usecase.GetUsers import com.hako.userlist.viewmodel.UserlistViewmodel @@ -10,7 +9,6 @@ import org.koin.dsl.module val userlistModules = module { factory { get().getClient(UserlistRemoteApi::class.java) } - factory { UserlistDatasource() } factory { GetUsers(get()) } viewModel { UserlistViewmodel() } diff --git a/userlist/src/main/java/com/hako/userlist/domain/datasource/UserlistDatasource.kt b/userlist/src/main/java/com/hako/userlist/domain/datasource/UserlistDatasource.kt deleted file mode 100644 index c9a6710..0000000 --- a/userlist/src/main/java/com/hako/userlist/domain/datasource/UserlistDatasource.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.hako.userlist.domain.datasource - -import com.hako.userlist.model.User -import io.reactivex.Single -import org.koin.core.KoinComponent -import org.koin.core.get - -class UserlistDatasource : KoinComponent, UserlistRemoteApi { - - private val api: UserlistRemoteApi = get() - - override fun getUsers(): Single> = api.getUsers() -} \ No newline at end of file diff --git a/userlist/src/main/java/com/hako/userlist/domain/usecase/GetUsers.kt b/userlist/src/main/java/com/hako/userlist/domain/usecase/GetUsers.kt index 939394d..d8a3fd1 100644 --- a/userlist/src/main/java/com/hako/userlist/domain/usecase/GetUsers.kt +++ b/userlist/src/main/java/com/hako/userlist/domain/usecase/GetUsers.kt @@ -2,7 +2,7 @@ package com.hako.userlist.domain.usecase import com.hako.base.domain.UseCase import com.hako.base.domain.database.dao.UserDao -import com.hako.userlist.domain.datasource.UserlistDatasource +import com.hako.userlist.domain.datasource.UserlistRemoteApi import com.hako.userlist.model.UserViewable import com.hako.userlist.model.toUserEntity import com.hako.userlist.model.toUserViewable @@ -14,7 +14,7 @@ import org.koin.core.get class GetUsers(private val dao: UserDao) : KoinComponent, UseCase { - private val api: UserlistDatasource = get() + private val api: UserlistRemoteApi = get() override fun execute( onSuccess: (List) -> Unit, From 2411c1c84d3b7428e8b660dffcb5f6a68746c708 Mon Sep 17 00:00:00 2001 From: Carlos Martinez Date: Mon, 3 Feb 2020 23:01:38 -0300 Subject: [PATCH 3/4] implement the album feature --- .../hako/albumlist/ExampleInstrumentedTest.kt | 24 ------ .../com/hako/albumlist/di/AlbumlistModules.kt | 15 ++++ .../domain/datasource/AlbumlistRemoteApi.kt | 14 ++++ .../hako/albumlist/domain/usecase/GetAlbum.kt | 42 ++++++++++ .../albumlist/feature/AlbumlistFragment.kt | 81 +++++++++++++++++++ .../com/hako/albumlist/model/AlbumModels.kt | 24 ++++++ .../albumlist/viewmodel/AlbumlistViewmodel.kt | 37 +++++++++ .../hako/albumlist/widget/AlbumlistAdapter.kt | 55 +++++++++++++ .../main/res/layout/fragment_albumlist.xml | 38 +++++++++ .../src/main/res/layout/item_album_card.xml | 27 +++++++ .../res/navigation/albumlist_navigation.xml | 14 ++++ .../com/hako/albumlist/ExampleUnitTest.kt | 17 ---- app/build.gradle | 1 + .../friendlists/ExampleInstrumentedTest.kt | 24 ------ .../com/hako/friendlists/MainApplication.kt | 4 +- .../main/res/navigation/main_navigation.xml | 4 +- app/src/main/res/values/colors.xml | 1 + app/src/main/res/values/styles.xml | 1 + .../com/hako/friendlists/ExampleUnitTest.kt | 17 ---- .../main/java/com/hako/base/domain/UseCase.kt | 5 -- .../hako/base/domain/database/dao/AlbumDao.kt | 3 + .../hako/userlist/domain/usecase/GetUsers.kt | 8 +- .../hako/userlist/feature/UserlistFragment.kt | 6 +- .../src/main/res/layout/item_user_card.xml | 3 +- 24 files changed, 367 insertions(+), 98 deletions(-) delete mode 100644 albumlist/src/androidTest/java/com/hako/albumlist/ExampleInstrumentedTest.kt create mode 100644 albumlist/src/main/java/com/hako/albumlist/di/AlbumlistModules.kt create mode 100644 albumlist/src/main/java/com/hako/albumlist/domain/datasource/AlbumlistRemoteApi.kt create mode 100644 albumlist/src/main/java/com/hako/albumlist/domain/usecase/GetAlbum.kt create mode 100644 albumlist/src/main/java/com/hako/albumlist/feature/AlbumlistFragment.kt create mode 100644 albumlist/src/main/java/com/hako/albumlist/model/AlbumModels.kt create mode 100644 albumlist/src/main/java/com/hako/albumlist/viewmodel/AlbumlistViewmodel.kt create mode 100644 albumlist/src/main/java/com/hako/albumlist/widget/AlbumlistAdapter.kt create mode 100644 albumlist/src/main/res/layout/fragment_albumlist.xml create mode 100644 albumlist/src/main/res/layout/item_album_card.xml create mode 100644 albumlist/src/main/res/navigation/albumlist_navigation.xml delete mode 100644 albumlist/src/test/java/com/hako/albumlist/ExampleUnitTest.kt delete mode 100644 app/src/androidTest/java/com/hako/friendlists/ExampleInstrumentedTest.kt delete mode 100644 app/src/test/java/com/hako/friendlists/ExampleUnitTest.kt delete mode 100644 base/src/main/java/com/hako/base/domain/UseCase.kt diff --git a/albumlist/src/androidTest/java/com/hako/albumlist/ExampleInstrumentedTest.kt b/albumlist/src/androidTest/java/com/hako/albumlist/ExampleInstrumentedTest.kt deleted file mode 100644 index 67e39df..0000000 --- a/albumlist/src/androidTest/java/com/hako/albumlist/ExampleInstrumentedTest.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.hako.albumlist - -import androidx.test.platform.app.InstrumentationRegistry -import androidx.test.ext.junit.runners.AndroidJUnit4 - -import org.junit.Test -import org.junit.runner.RunWith - -import org.junit.Assert.* - -/** - * Instrumented test, which will execute on an Android device. - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -@RunWith(AndroidJUnit4::class) -class ExampleInstrumentedTest { - @Test - fun useAppContext() { - // Context of the app under test. - val appContext = InstrumentationRegistry.getInstrumentation().targetContext - assertEquals("com.hako.albumlist.test", appContext.packageName) - } -} diff --git a/albumlist/src/main/java/com/hako/albumlist/di/AlbumlistModules.kt b/albumlist/src/main/java/com/hako/albumlist/di/AlbumlistModules.kt new file mode 100644 index 0000000..a578b68 --- /dev/null +++ b/albumlist/src/main/java/com/hako/albumlist/di/AlbumlistModules.kt @@ -0,0 +1,15 @@ +package com.hako.albumlist.di + +import com.hako.albumlist.domain.datasource.AlbumlistRemoteApi +import com.hako.albumlist.domain.usecase.GetAlbum +import com.hako.albumlist.viewmodel.AlbumlistViewmodel +import com.hako.base.domain.network.RemoteClient +import org.koin.androidx.viewmodel.dsl.viewModel +import org.koin.dsl.module + +val albumListModules = module { + factory { get().getClient(AlbumlistRemoteApi::class.java) } + factory { GetAlbum(get()) } + + viewModel { AlbumlistViewmodel() } +} \ No newline at end of file diff --git a/albumlist/src/main/java/com/hako/albumlist/domain/datasource/AlbumlistRemoteApi.kt b/albumlist/src/main/java/com/hako/albumlist/domain/datasource/AlbumlistRemoteApi.kt new file mode 100644 index 0000000..249822e --- /dev/null +++ b/albumlist/src/main/java/com/hako/albumlist/domain/datasource/AlbumlistRemoteApi.kt @@ -0,0 +1,14 @@ +package com.hako.albumlist.domain.datasource + +import com.hako.albumlist.model.Album +import io.reactivex.Single +import retrofit2.http.GET +import retrofit2.http.Query + +interface AlbumlistRemoteApi { + + @GET("/albums") + fun getAlbums( + @Query("userId") userId: Int + ): Single> +} \ No newline at end of file diff --git a/albumlist/src/main/java/com/hako/albumlist/domain/usecase/GetAlbum.kt b/albumlist/src/main/java/com/hako/albumlist/domain/usecase/GetAlbum.kt new file mode 100644 index 0000000..8ec47e6 --- /dev/null +++ b/albumlist/src/main/java/com/hako/albumlist/domain/usecase/GetAlbum.kt @@ -0,0 +1,42 @@ +package com.hako.albumlist.domain.usecase + +import com.hako.albumlist.domain.datasource.AlbumlistRemoteApi +import com.hako.albumlist.model.AlbumViewable +import com.hako.albumlist.model.toAlbumEntity +import com.hako.albumlist.model.toUserViewable +import com.hako.base.domain.database.dao.AlbumDao +import io.reactivex.Single +import io.reactivex.schedulers.Schedulers +import org.koin.core.KoinComponent +import org.koin.core.get + +class GetAlbum(private val dao: AlbumDao) : KoinComponent { + + private val api: AlbumlistRemoteApi = get() + + fun execute( + userId: Int, + onSuccess: (List) -> Unit, + onError: (Throwable) -> Unit, + onLoading: () -> Unit + ) { + Single.fromCallable { dao.getAlbums(userId) } + .subscribeOn(Schedulers.io()) + .doOnError { onError(it) } + .doOnSuccess { dbAlbum -> + if (dbAlbum.isEmpty() || dbAlbum.count() == 0) { + api.getAlbums(userId) + .doOnSuccess { + dao.saveAll(it.map { album -> album.toAlbumEntity() }) + onSuccess(dao.getAlbums(userId).map { album -> album.toUserViewable() }) + } + .doOnSubscribe { onLoading() } + .subscribeOn(Schedulers.io()) + .subscribe({}, { onError(it) }) + } else { + onSuccess(dbAlbum.map { it.toUserViewable() }) + } + } + .subscribe() + } +} diff --git a/albumlist/src/main/java/com/hako/albumlist/feature/AlbumlistFragment.kt b/albumlist/src/main/java/com/hako/albumlist/feature/AlbumlistFragment.kt new file mode 100644 index 0000000..e022482 --- /dev/null +++ b/albumlist/src/main/java/com/hako/albumlist/feature/AlbumlistFragment.kt @@ -0,0 +1,81 @@ +package com.hako.albumlist.feature + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import androidx.recyclerview.widget.LinearLayoutManager +import com.hako.albumlist.R +import com.hako.albumlist.model.AlbumViewable +import com.hako.albumlist.viewmodel.AlbumlistViewmodel +import com.hako.albumlist.widget.AlbumlistAdapter +import com.hako.base.domain.network.RequestStatus +import com.hako.base.extensions.gone +import com.hako.base.extensions.observeNonNull +import com.hako.base.extensions.toast +import com.hako.base.extensions.visible +import kotlinx.android.synthetic.main.fragment_albumlist.* +import org.koin.androidx.viewmodel.ext.android.viewModel +import timber.log.Timber + +class AlbumlistFragment : Fragment() { + + private val viewModel: AlbumlistViewmodel by viewModel() + private val listAdapter by lazy { AlbumlistAdapter() } + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? + ): View = inflater.inflate(R.layout.fragment_albumlist, container, false) + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + setRecycler() + setObservers() + + //TODO: Get user by bundle + viewModel.fetchAlbums(2) + } + + private fun setObservers() { + viewModel.data.observeNonNull(this) { + it.either(::handleFetchError, ::handleFetchSuccess) + } + + viewModel.requestStatus.observeNonNull(this) { + when (it) { + RequestStatus.Ready -> { + fragment_albumlist_error_overlay.gone() + fragment_albumlist_loading_overlay.gone() + } + RequestStatus.Loading -> { + fragment_albumlist_error_overlay.gone() + fragment_albumlist_loading_overlay.visible() + } + RequestStatus.Errored -> { + fragment_albumlist_error_overlay.visible() + fragment_albumlist_loading_overlay.gone() + } + } + } + } + + private fun handleFetchError(throwable: Throwable) { + Timber.e(throwable) + } + + private fun handleFetchSuccess(users: List) { + listAdapter.addAll(users) + } + + private fun setRecycler() { + fragment_albumlist_recycler_container.apply { + layoutManager = LinearLayoutManager(context) + adapter = listAdapter.apply { + onItemClick = { + context.toast(it.title) + } + } + } + } +} \ No newline at end of file diff --git a/albumlist/src/main/java/com/hako/albumlist/model/AlbumModels.kt b/albumlist/src/main/java/com/hako/albumlist/model/AlbumModels.kt new file mode 100644 index 0000000..c61f6b7 --- /dev/null +++ b/albumlist/src/main/java/com/hako/albumlist/model/AlbumModels.kt @@ -0,0 +1,24 @@ +package com.hako.albumlist.model + +import android.os.Parcelable +import com.google.gson.annotations.SerializedName +import com.hako.base.domain.database.entities.AlbumEntity +import kotlinx.android.parcel.Parcelize + +@Parcelize +data class Album( + @SerializedName("id") val id: Int, + @SerializedName("userId") val userId: Int, + @SerializedName("title") val title: String +) : Parcelable + +data class AlbumViewable( + val id: Int, + val userId: Int, + val title: String +) + +fun Album.toAlbumEntity() = AlbumEntity(this.id, this.userId, this.title) + +fun AlbumEntity.toUserViewable() = AlbumViewable(this.id, this.userId, this.title) + diff --git a/albumlist/src/main/java/com/hako/albumlist/viewmodel/AlbumlistViewmodel.kt b/albumlist/src/main/java/com/hako/albumlist/viewmodel/AlbumlistViewmodel.kt new file mode 100644 index 0000000..f3f3bbc --- /dev/null +++ b/albumlist/src/main/java/com/hako/albumlist/viewmodel/AlbumlistViewmodel.kt @@ -0,0 +1,37 @@ +package com.hako.albumlist.viewmodel + +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import com.hako.albumlist.domain.usecase.GetAlbum +import com.hako.albumlist.model.AlbumViewable +import com.hako.base.domain.network.RequestStatus +import com.hako.base.domain.network.RequestStatus.Ready +import com.hako.base.domain.network.RequestStatus.Loading +import com.hako.base.domain.network.RequestStatus.Errored +import com.hako.base.domain.Either +import org.koin.core.KoinComponent +import org.koin.core.get + +class AlbumlistViewmodel : ViewModel(), KoinComponent { + + val data = MutableLiveData>>() + val requestStatus = MutableLiveData() + + private val getUsers: GetAlbum = get() + + fun fetchAlbums(userId: Int) { + getUsers.execute( + userId, + onSuccess = { + requestStatus.postValue(Ready) + data.postValue(Either.Right(it)) + }, + onLoading = { + requestStatus.postValue(Loading) + }, + onError = { + requestStatus.postValue(Errored) + data.postValue(Either.Left(it)) + }) + } +} diff --git a/albumlist/src/main/java/com/hako/albumlist/widget/AlbumlistAdapter.kt b/albumlist/src/main/java/com/hako/albumlist/widget/AlbumlistAdapter.kt new file mode 100644 index 0000000..fd646a7 --- /dev/null +++ b/albumlist/src/main/java/com/hako/albumlist/widget/AlbumlistAdapter.kt @@ -0,0 +1,55 @@ +package com.hako.albumlist.widget + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import com.hako.albumlist.R +import com.hako.albumlist.model.AlbumViewable +import com.hako.base.extensions.autoNotify +import kotlinx.android.synthetic.main.item_album_card.view.* +import kotlin.properties.Delegates + +class AlbumlistAdapter : RecyclerView.Adapter() { + + private var items by Delegates.observable(emptyList()) { _, oldList, newList -> + autoNotify(oldList, newList) { old, new -> old.id == new.id } + notifyDataSetChanged() + } + + var onItemClick: (AlbumViewable) -> Unit = { } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder = + UserViewHolder( + LayoutInflater + .from(parent.context) + .inflate(R.layout.item_album_card, parent, false), + onItemClick + ) + + fun getItem(position: Int) = items[position] + + fun addAll(list: List) { + items = list + } + + override fun getItemCount() = items.size + + override fun onBindViewHolder(viewholder: RecyclerView.ViewHolder, position: Int) = + when (viewholder) { + is UserViewHolder -> viewholder.bind(items[position]) + else -> throw NoWhenBranchMatchedException("Undefined viewholder") + } +} + +class UserViewHolder(private val view: View, + private val onItemClick: (AlbumViewable) -> Unit) : + RecyclerView.ViewHolder(view) { + + fun bind(album: AlbumViewable) = with(view) { + item_album_card_album_name.text = album.title + item_album_card_container.setOnClickListener { + onItemClick(album) + } + } +} \ No newline at end of file diff --git a/albumlist/src/main/res/layout/fragment_albumlist.xml b/albumlist/src/main/res/layout/fragment_albumlist.xml new file mode 100644 index 0000000..9d1244f --- /dev/null +++ b/albumlist/src/main/res/layout/fragment_albumlist.xml @@ -0,0 +1,38 @@ + + + + + + + + + + \ No newline at end of file diff --git a/albumlist/src/main/res/layout/item_album_card.xml b/albumlist/src/main/res/layout/item_album_card.xml new file mode 100644 index 0000000..0a77049 --- /dev/null +++ b/albumlist/src/main/res/layout/item_album_card.xml @@ -0,0 +1,27 @@ + + + + + + \ No newline at end of file diff --git a/albumlist/src/main/res/navigation/albumlist_navigation.xml b/albumlist/src/main/res/navigation/albumlist_navigation.xml new file mode 100644 index 0000000..68a54ee --- /dev/null +++ b/albumlist/src/main/res/navigation/albumlist_navigation.xml @@ -0,0 +1,14 @@ + + + + + + \ No newline at end of file diff --git a/albumlist/src/test/java/com/hako/albumlist/ExampleUnitTest.kt b/albumlist/src/test/java/com/hako/albumlist/ExampleUnitTest.kt deleted file mode 100644 index b865887..0000000 --- a/albumlist/src/test/java/com/hako/albumlist/ExampleUnitTest.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.hako.albumlist - -import org.junit.Test - -import org.junit.Assert.* - -/** - * Example local unit test, which will execute on the development machine (host). - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -class ExampleUnitTest { - @Test - fun addition_isCorrect() { - assertEquals(4, 2 + 2) - } -} diff --git a/app/build.gradle b/app/build.gradle index 2f3e31f..3019374 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -49,4 +49,5 @@ android { dependencies { implementation project(":base") implementation project(":userlist") + implementation project(":albumlist") } diff --git a/app/src/androidTest/java/com/hako/friendlists/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/hako/friendlists/ExampleInstrumentedTest.kt deleted file mode 100644 index 4d61923..0000000 --- a/app/src/androidTest/java/com/hako/friendlists/ExampleInstrumentedTest.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.hako.friendlists - -import androidx.test.platform.app.InstrumentationRegistry -import androidx.test.ext.junit.runners.AndroidJUnit4 - -import org.junit.Test -import org.junit.runner.RunWith - -import org.junit.Assert.* - -/** - * Instrumented test, which will execute on an Android device. - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -@RunWith(AndroidJUnit4::class) -class ExampleInstrumentedTest { - @Test - fun useAppContext() { - // Context of the app under test. - val appContext = InstrumentationRegistry.getInstrumentation().targetContext - assertEquals("com.hako.friendlists", appContext.packageName) - } -} diff --git a/app/src/main/java/com/hako/friendlists/MainApplication.kt b/app/src/main/java/com/hako/friendlists/MainApplication.kt index 92db1b3..fed3f18 100644 --- a/app/src/main/java/com/hako/friendlists/MainApplication.kt +++ b/app/src/main/java/com/hako/friendlists/MainApplication.kt @@ -1,6 +1,7 @@ package com.hako.friendlists import android.app.Application +import com.hako.albumlist.di.albumListModules import com.hako.userlist.di.userlistModules import com.hako.friendlists.di.appModules import org.koin.android.ext.koin.androidContext @@ -26,7 +27,8 @@ class MainApplication : Application() { modules( listOf( appModules, - userlistModules + userlistModules, + albumListModules ) ) } diff --git a/app/src/main/res/navigation/main_navigation.xml b/app/src/main/res/navigation/main_navigation.xml index 4befeb8..0893043 100644 --- a/app/src/main/res/navigation/main_navigation.xml +++ b/app/src/main/res/navigation/main_navigation.xml @@ -2,8 +2,10 @@ + app:startDestination="@id/albumlist_navigation"> + + \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 3743e89..ecb305d 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -4,4 +4,5 @@ #324047 #CBCFD1 #D32F2F + #333333 diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index f69921a..825a3e6 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -5,6 +5,7 @@ @color/colorPrimaryDark @color/colorAccent @color/soft_background + @color/colorDarkGray diff --git a/app/src/test/java/com/hako/friendlists/ExampleUnitTest.kt b/app/src/test/java/com/hako/friendlists/ExampleUnitTest.kt deleted file mode 100644 index 7652373..0000000 --- a/app/src/test/java/com/hako/friendlists/ExampleUnitTest.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.hako.friendlists - -import org.junit.Test - -import org.junit.Assert.* - -/** - * Example local unit test, which will execute on the development machine (host). - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -class ExampleUnitTest { - @Test - fun addition_isCorrect() { - assertEquals(4, 2 + 2) - } -} diff --git a/base/src/main/java/com/hako/base/domain/UseCase.kt b/base/src/main/java/com/hako/base/domain/UseCase.kt deleted file mode 100644 index d9e178c..0000000 --- a/base/src/main/java/com/hako/base/domain/UseCase.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.hako.base.domain - -interface UseCase { - fun execute(onSuccess: (List) -> Unit, onError: (Throwable) -> Unit, onLoading: () -> Unit) -} \ No newline at end of file diff --git a/base/src/main/java/com/hako/base/domain/database/dao/AlbumDao.kt b/base/src/main/java/com/hako/base/domain/database/dao/AlbumDao.kt index 3a395de..6d22584 100644 --- a/base/src/main/java/com/hako/base/domain/database/dao/AlbumDao.kt +++ b/base/src/main/java/com/hako/base/domain/database/dao/AlbumDao.kt @@ -18,6 +18,9 @@ interface AlbumDao { @get:Query("SELECT * FROM ${AlbumEntity.TABLE_NAME}") val all: List + @Query("SELECT * FROM ${AlbumEntity.TABLE_NAME} WHERE userId = :userId ORDER BY id ASC") + fun getAlbums(userId: Int): List + @Query("SELECT COUNT(*) FROM ${AlbumEntity.TABLE_NAME}") fun count(): Int diff --git a/userlist/src/main/java/com/hako/userlist/domain/usecase/GetUsers.kt b/userlist/src/main/java/com/hako/userlist/domain/usecase/GetUsers.kt index d8a3fd1..864a693 100644 --- a/userlist/src/main/java/com/hako/userlist/domain/usecase/GetUsers.kt +++ b/userlist/src/main/java/com/hako/userlist/domain/usecase/GetUsers.kt @@ -1,6 +1,5 @@ package com.hako.userlist.domain.usecase -import com.hako.base.domain.UseCase import com.hako.base.domain.database.dao.UserDao import com.hako.userlist.domain.datasource.UserlistRemoteApi import com.hako.userlist.model.UserViewable @@ -11,12 +10,11 @@ import io.reactivex.schedulers.Schedulers import org.koin.core.KoinComponent import org.koin.core.get -class GetUsers(private val dao: UserDao) : KoinComponent, - UseCase { +class GetUsers(private val dao: UserDao) : KoinComponent { private val api: UserlistRemoteApi = get() - override fun execute( + fun execute( onSuccess: (List) -> Unit, onError: (Throwable) -> Unit, onLoading: () -> Unit @@ -25,7 +23,7 @@ class GetUsers(private val dao: UserDao) : KoinComponent, .subscribeOn(Schedulers.io()) .doOnError { onError(it) } .doOnSuccess { dbUsers -> - if (dbUsers.isEmpty() || dbUsers.count() == 0) { + if (dbUsers.isEmpty()) { api.getUsers() .doOnSuccess { dao.saveAll(it.map { user -> user.toUserEntity() }) diff --git a/userlist/src/main/java/com/hako/userlist/feature/UserlistFragment.kt b/userlist/src/main/java/com/hako/userlist/feature/UserlistFragment.kt index 7f02c67..b34fbd8 100644 --- a/userlist/src/main/java/com/hako/userlist/feature/UserlistFragment.kt +++ b/userlist/src/main/java/com/hako/userlist/feature/UserlistFragment.kt @@ -22,7 +22,7 @@ import timber.log.Timber class UserlistFragment : Fragment() { private val viewModel: UserlistViewmodel by viewModel() - private val chatAdapter by lazy { UserlistAdapter() } + private val listAdapter by lazy { UserlistAdapter() } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? @@ -63,13 +63,13 @@ class UserlistFragment : Fragment() { } private fun handleFetchSuccess(users: List) { - chatAdapter.addAll(users) + listAdapter.addAll(users) } private fun setRecycler() { fragment_userlist_recycler_container.apply { layoutManager = LinearLayoutManager(context) - adapter = chatAdapter.apply { + adapter = listAdapter.apply { onItemClick = { context.toast(it.realName) } diff --git a/userlist/src/main/res/layout/item_user_card.xml b/userlist/src/main/res/layout/item_user_card.xml index 524ef91..36a66aa 100644 --- a/userlist/src/main/res/layout/item_user_card.xml +++ b/userlist/src/main/res/layout/item_user_card.xml @@ -19,6 +19,7 @@ android:layout_marginStart="24dp" android:layout_marginTop="16dp" android:textSize="18sp" + android:textStyle="bold" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" tools:text="Real Name" /> @@ -27,7 +28,7 @@ android:id="@+id/item_user_card_user_name" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textSize="12sp" + android:textSize="14sp" app:layout_constraintStart_toStartOf="@+id/item_user_card_real_name" app:layout_constraintTop_toBottomOf="@+id/item_user_card_real_name" tools:text="User Name" /> From 0dedc1edceff3324c3d0e80ce3eb671da7d24ba9 Mon Sep 17 00:00:00 2001 From: Carlos Martinez Date: Tue, 4 Feb 2020 20:41:18 -0300 Subject: [PATCH 4/4] clean up code --- .../main/java/com/hako/albumlist/feature/AlbumlistFragment.kt | 3 +-- albumlist/src/main/res/layout/item_album_card.xml | 2 +- app/src/main/res/navigation/main_navigation.xml | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/albumlist/src/main/java/com/hako/albumlist/feature/AlbumlistFragment.kt b/albumlist/src/main/java/com/hako/albumlist/feature/AlbumlistFragment.kt index e022482..e7a4eca 100644 --- a/albumlist/src/main/java/com/hako/albumlist/feature/AlbumlistFragment.kt +++ b/albumlist/src/main/java/com/hako/albumlist/feature/AlbumlistFragment.kt @@ -32,8 +32,7 @@ class AlbumlistFragment : Fragment() { super.onViewCreated(view, savedInstanceState) setRecycler() setObservers() - - //TODO: Get user by bundle + // TODO: Get user by bundle viewModel.fetchAlbums(2) } diff --git a/albumlist/src/main/res/layout/item_album_card.xml b/albumlist/src/main/res/layout/item_album_card.xml index 0a77049..162c57f 100644 --- a/albumlist/src/main/res/layout/item_album_card.xml +++ b/albumlist/src/main/res/layout/item_album_card.xml @@ -22,6 +22,6 @@ android:textStyle="bold" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" - tools:text="Real Name" /> + tools:text="Album name" /> \ No newline at end of file diff --git a/app/src/main/res/navigation/main_navigation.xml b/app/src/main/res/navigation/main_navigation.xml index 0893043..ae60acb 100644 --- a/app/src/main/res/navigation/main_navigation.xml +++ b/app/src/main/res/navigation/main_navigation.xml @@ -2,7 +2,7 @@ + app:startDestination="@id/userlist_navigation">