mirror of
https://github.com/imcarlost/Friendlists.git
synced 2026-04-10 02:46:54 -04:00
migrate to multidatabase structure and clean up code
This commit is contained in:
@@ -1,8 +1,12 @@
|
||||
apply plugin: 'com.android.library'
|
||||
apply from: '../core.gradle'
|
||||
|
||||
android {
|
||||
defaultConfig {
|
||||
buildConfigField "String", "DB_NAME", '"photolist.db"'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation project(':base')
|
||||
testImplementation project(':testing')
|
||||
androidTestImplementation project(':testing')
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
package com.hako.photolist.di
|
||||
|
||||
import androidx.room.Room
|
||||
import com.hako.base.domain.network.RemoteClient
|
||||
import com.hako.photolist.BuildConfig
|
||||
import com.hako.photolist.domain.clients.LocalClient
|
||||
import com.hako.photolist.domain.datasource.PhotolistRemoteApi
|
||||
import com.hako.photolist.domain.usecase.GetPhoto
|
||||
import com.hako.photolist.viewmodel.PhotolistViewmodel
|
||||
@@ -8,8 +11,12 @@ import org.koin.androidx.viewmodel.dsl.viewModel
|
||||
import org.koin.dsl.module
|
||||
|
||||
val photoListModules = module {
|
||||
|
||||
single { Room.databaseBuilder(get(), LocalClient::class.java, BuildConfig.DB_NAME).build() }
|
||||
factory { get<LocalClient>().photoDao() }
|
||||
|
||||
factory { get<RemoteClient>().getClient(PhotolistRemoteApi::class.java) }
|
||||
factory { GetPhoto(get()) }
|
||||
factory { GetPhoto(get(), get()) }
|
||||
|
||||
viewModel { PhotolistViewmodel() }
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.hako.photolist.domain.clients
|
||||
|
||||
import androidx.room.Database
|
||||
import androidx.room.RoomDatabase
|
||||
import com.hako.photolist.domain.datasource.PhotoDao
|
||||
import com.hako.photolist.model.PhotoEntity
|
||||
|
||||
@Database(entities = [PhotoEntity::class], version = 1, exportSchema = false)
|
||||
abstract class LocalClient : RoomDatabase() {
|
||||
abstract fun photoDao(): PhotoDao
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.hako.photolist.domain.datasource
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import com.hako.photolist.model.PhotoEntity
|
||||
|
||||
@Dao
|
||||
interface PhotoDao {
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun save(entity: PhotoEntity)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun saveAll(entities: List<PhotoEntity>)
|
||||
|
||||
@Query("SELECT * FROM ${PhotoEntity.TABLE_NAME} WHERE albumId = :albumId ORDER BY id ASC")
|
||||
fun getPhotos(albumId: Int): List<PhotoEntity>
|
||||
|
||||
@Query("SELECT COUNT(*) FROM ${PhotoEntity.TABLE_NAME}")
|
||||
fun count(): Int
|
||||
|
||||
@Query("DELETE FROM ${PhotoEntity.TABLE_NAME}")
|
||||
fun nukeDatabase()
|
||||
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.hako.photolist.domain.datasource
|
||||
|
||||
import com.hako.photolist.model.Photo
|
||||
import com.hako.photolist.model.PhotoRemote
|
||||
import io.reactivex.Single
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.Query
|
||||
@@ -10,5 +10,5 @@ interface PhotolistRemoteApi {
|
||||
@GET("/photos")
|
||||
fun getPhotos(
|
||||
@Query("albumId") albumId: Int
|
||||
): Single<List<Photo>>
|
||||
): Single<List<PhotoRemote>>
|
||||
}
|
||||
@@ -1,20 +1,16 @@
|
||||
package com.hako.photolist.domain.usecase
|
||||
|
||||
import com.hako.base.domain.database.dao.PhotoDao
|
||||
import com.hako.photolist.domain.datasource.PhotoDao
|
||||
import com.hako.photolist.domain.datasource.PhotolistRemoteApi
|
||||
import com.hako.photolist.model.*
|
||||
import io.reactivex.Single
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import org.koin.core.KoinComponent
|
||||
import org.koin.core.get
|
||||
|
||||
class GetPhoto(private val dao: PhotoDao) : KoinComponent {
|
||||
|
||||
private val api: PhotolistRemoteApi = get()
|
||||
class GetPhoto(private val dao: PhotoDao, private val api: PhotolistRemoteApi) {
|
||||
|
||||
fun execute(
|
||||
albumId: Int,
|
||||
onSuccess: (List<PhotoViewable>) -> Unit,
|
||||
onSuccess: (List<Photo>) -> Unit,
|
||||
onError: (Throwable) -> Unit,
|
||||
onLoading: () -> Unit
|
||||
) {
|
||||
|
||||
@@ -11,7 +11,7 @@ import com.hako.base.extensions.gone
|
||||
import com.hako.base.extensions.observeNonNull
|
||||
import com.hako.base.extensions.visible
|
||||
import com.hako.photolist.R
|
||||
import com.hako.photolist.model.PhotoViewable
|
||||
import com.hako.photolist.model.Photo
|
||||
import com.hako.photolist.viewmodel.PhotolistViewmodel
|
||||
import com.hako.photolist.widget.PhotolistAdapter
|
||||
import kotlinx.android.synthetic.main.fragment_photolist.*
|
||||
@@ -68,7 +68,7 @@ class PhotolistFragment : Fragment() {
|
||||
Timber.e(throwable)
|
||||
}
|
||||
|
||||
private fun handleFetchSuccess(photos: List<PhotoViewable>) {
|
||||
private fun handleFetchSuccess(photos: List<Photo>) {
|
||||
listAdapter.addAll(photos)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
package com.hako.photolist.model
|
||||
|
||||
import android.os.Parcelable
|
||||
import androidx.room.Entity
|
||||
import androidx.room.Index
|
||||
import androidx.room.PrimaryKey
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import com.hako.base.domain.database.entities.PhotoEntity
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
|
||||
@Parcelize
|
||||
data class Photo(
|
||||
data class PhotoRemote(
|
||||
@SerializedName("id") val id: Int,
|
||||
@SerializedName("albumId") val albumId: Int,
|
||||
@SerializedName("title") val title: String,
|
||||
@@ -14,14 +16,28 @@ data class Photo(
|
||||
@SerializedName("thumbnailUrl") val thumbnailUrl: String
|
||||
) : Parcelable
|
||||
|
||||
data class PhotoViewable(
|
||||
@Entity(tableName = PhotoEntity.TABLE_NAME, indices = [Index(value = ["id"], unique = true)])
|
||||
data class PhotoEntity(
|
||||
@PrimaryKey
|
||||
val id: Int,
|
||||
val albumId: Int,
|
||||
val title: String,
|
||||
val photoUrl: String,
|
||||
val thumbnailUrl: String
|
||||
) {
|
||||
companion object {
|
||||
const val TABLE_NAME = "photos"
|
||||
}
|
||||
}
|
||||
|
||||
data class Photo(
|
||||
val id: Int,
|
||||
val albumId: Int,
|
||||
val title: String,
|
||||
val photoUrl: String
|
||||
)
|
||||
|
||||
fun Photo.toPhotoEntity() = PhotoEntity(this.id, this.albumId, this.title, this.photoUrl, this.thumbnailUrl)
|
||||
fun PhotoRemote.toPhotoEntity() = PhotoEntity(this.id, this.albumId, this.title, this.photoUrl, this.thumbnailUrl)
|
||||
|
||||
fun PhotoEntity.toPhotoViewable() = PhotoViewable(this.id, this.albumId, this.title, this.photoUrl)
|
||||
fun PhotoEntity.toPhotoViewable() = Photo(this.id, this.albumId, this.title, this.photoUrl)
|
||||
|
||||
|
||||
@@ -8,13 +8,13 @@ import com.hako.base.domain.network.RequestStatus.Loading
|
||||
import com.hako.base.domain.network.RequestStatus.Errored
|
||||
import com.hako.base.domain.Either
|
||||
import com.hako.photolist.domain.usecase.GetPhoto
|
||||
import com.hako.photolist.model.PhotoViewable
|
||||
import com.hako.photolist.model.Photo
|
||||
import org.koin.core.KoinComponent
|
||||
import org.koin.core.get
|
||||
|
||||
class PhotolistViewmodel : ViewModel(), KoinComponent {
|
||||
|
||||
val data = MutableLiveData<Either<Throwable, List<PhotoViewable>>>()
|
||||
val data = MutableLiveData<Either<Throwable, List<Photo>>>()
|
||||
val requestStatus = MutableLiveData<RequestStatus>()
|
||||
|
||||
private val getPhoto: GetPhoto = get()
|
||||
|
||||
@@ -6,7 +6,7 @@ import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.hako.base.extensions.autoNotify
|
||||
import com.hako.photolist.R
|
||||
import com.hako.photolist.model.PhotoViewable
|
||||
import com.hako.photolist.model.Photo
|
||||
import com.squareup.picasso.Picasso
|
||||
import kotlinx.android.synthetic.main.item_photo_card.view.*
|
||||
import org.koin.core.KoinComponent
|
||||
@@ -15,7 +15,7 @@ import kotlin.properties.Delegates
|
||||
|
||||
class PhotolistAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||
|
||||
private var items by Delegates.observable(emptyList<PhotoViewable>()) { _, oldList, newList ->
|
||||
private var items by Delegates.observable(emptyList<Photo>()) { _, oldList, newList ->
|
||||
autoNotify(oldList, newList) { old, new -> old.id == new.id }
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
@@ -29,7 +29,7 @@ class PhotolistAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||
|
||||
fun getItem(position: Int) = items[position]
|
||||
|
||||
fun addAll(list: List<PhotoViewable>) {
|
||||
fun addAll(list: List<Photo>) {
|
||||
items = list
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ class PhotoViewHolder(private val view: View) :
|
||||
|
||||
private val picasso: Picasso by inject()
|
||||
|
||||
fun bind(photo: PhotoViewable) = with(view) {
|
||||
fun bind(photo: Photo) = with(view) {
|
||||
picasso.load(photo.photoUrl)
|
||||
.placeholder(R.drawable.img_photo_placeholder)
|
||||
.fit()
|
||||
|
||||
Reference in New Issue
Block a user