Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 67d75de

Browse files
finish post status with display count and like
1 parent 3c5404b commit 67d75de

File tree

14 files changed

+132
-27
lines changed

14 files changed

+132
-27
lines changed

‎app/src/main/java/com/smarttoolfactory/postdynamichilt/ViewBindings.kt‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.smarttoolfactory.postdynamichilt
22

33
import android.view.View
4+
import android.widget.ImageButton
45
import android.widget.ImageView
56
import androidx.databinding.BindingAdapter
67
import androidx.recyclerview.widget.ListAdapter
@@ -79,3 +80,12 @@ fun setImageUrl(view: ImageView, userId: Int) {
7980
fun View.visibilityBasedOn(condition: Boolean) {
8081
visibility = if (condition) View.VISIBLE else View.GONE
8182
}
83+
84+
@BindingAdapter("favoriteImageSrc")
85+
fun ImageButton.setFavoriteImageSrc(favorite: Boolean) {
86+
87+
val imageResource = if (favorite) R.drawable.ic_baseline_thumb_up_24
88+
else R.drawable.ic_outline_thumb_up_24
89+
90+
setImageResource(imageResource)
91+
}

‎app/src/main/java/com/smarttoolfactory/postdynamichilt/postlist/PostListAdapter.kt‎

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.smarttoolfactory.postdynamichilt.postlist
22

33
import android.view.LayoutInflater
44
import android.view.ViewGroup
5+
import android.widget.ImageButton
56
import androidx.annotation.LayoutRes
67
import androidx.databinding.DataBindingUtil
78
import androidx.databinding.ViewDataBinding
@@ -10,12 +11,14 @@ import androidx.recyclerview.widget.ListAdapter
1011
import androidx.recyclerview.widget.RecyclerView
1112
import com.smarttoolfactory.domain.model.Post
1213
import com.smarttoolfactory.postdynamichilt.BR
14+
import com.smarttoolfactory.postdynamichilt.R
15+
import kotlinx.android.synthetic.main.row_post.view.*
1316

1417
class PostListAdapter(
1518

1619
@LayoutRes private val layoutId: Int,
17-
private val onItemClicked: ((Post) -> Unit)? = null
18-
20+
private val onItemClicked: ((Post) -> Unit)? = null,
21+
privatevalonLikeButtonClicked: ((Post) ->Unit)? = null
1922
) :
2023
ListAdapter<Post, PostListAdapter.CustomViewHolder<Post>>(
2124
PostDiffCallback()
@@ -34,9 +37,7 @@ class PostListAdapter(
3437
false
3538
)
3639

37-
return CustomViewHolder<Post>(
38-
binding
39-
)
40+
return CustomViewHolder<Post>(binding)
4041
.apply {
4142
onViewHolderCreated(this, binding)
4243
}
@@ -56,6 +57,25 @@ class PostListAdapter(
5657
it((getItem(viewHolder.bindingAdapterPosition)))
5758
}
5859
}
60+
61+
binding.root.ivLike.setOnClickListener { likeButton ->
62+
onLikeButtonClicked?.let { onLikeButtonClick ->
63+
64+
getItem(viewHolder.bindingAdapterPosition).apply {
65+
// Change like status of Post
66+
isFavorite = !isFavorite
67+
onLikeButtonClick(this)
68+
69+
// Set image source of like button
70+
val imageResource = if (isFavorite) {
71+
R.drawable.ic_baseline_thumb_up_24
72+
} else {
73+
R.drawable.ic_outline_thumb_up_24
74+
}
75+
(likeButton as? ImageButton)?.setImageResource(imageResource)
76+
}
77+
}
78+
}
5979
}
6080

6181
override fun onBindViewHolder(holder: CustomViewHolder<Post>, position: Int) {

‎app/src/main/java/com/smarttoolfactory/postdynamichilt/postlist/PostListFragment.kt‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class PostListFragment : DynamicNavigationFragment<FragmentPostListBinding>() {
1616

1717
override fun getLayoutRes(): Int = R.layout.fragment_post_list
1818

19-
// private val viewModel: PostListViewModel by viewModels()
19+
// private val viewModel: PostListViewModel by viewModels()
2020
private val viewModel: PostStatusViewModel by viewModels()
2121

2222
private lateinit var postListAdapter: PostListAdapter
@@ -27,7 +27,6 @@ class PostListFragment : DynamicNavigationFragment<FragmentPostListBinding>() {
2727
}
2828

2929
override fun bindViews() {
30-
3130
dataBinding.viewModel = viewModel
3231

3332
dataBinding.recyclerView.apply {
@@ -38,7 +37,8 @@ class PostListFragment : DynamicNavigationFragment<FragmentPostListBinding>() {
3837

3938
postListAdapter = PostListAdapter(
4039
R.layout.row_post,
41-
viewModel::onClick
40+
viewModel::onClick,
41+
viewModel::onLikeButtonClick
4242
)
4343

4444
// Set RecyclerViewAdapter

‎app/src/main/java/com/smarttoolfactory/postdynamichilt/postlist/PostStatusViewModel.kt‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ import com.smarttoolfactory.core.viewstate.ViewState
1111
import com.smarttoolfactory.domain.model.Post
1212
import com.smarttoolfactory.domain.usecase.GetPostsWithStatusUseCaseFlow
1313
import kotlinx.coroutines.CoroutineScope
14+
import kotlinx.coroutines.flow.catch
1415
import kotlinx.coroutines.flow.launchIn
16+
import kotlinx.coroutines.flow.onCompletion
1517
import kotlinx.coroutines.flow.onEach
1618
import kotlinx.coroutines.flow.onStart
1719

@@ -69,7 +71,28 @@ class PostStatusViewModel @ViewModelInject constructor(
6971
.launchIn(coroutineScope)
7072
}
7173

74+
fun updatePostStatus(post: Post) {
75+
getPostsUseCase.updatePostStatus(post)
76+
.onStart { println("⏰ PostStatusViewModel updatePostStatus() catch() onStart") }
77+
.catch { throwable ->
78+
println("❌ PostStatusViewModel updatePostStatus() catch(): ${throwable.message}")
79+
}
80+
.onCompletion { cause: Throwable? ->
81+
println(
82+
"💀 PostStatusViewModel updatePostStatus() " +
83+
"onCompletion() error: ${cause != null}"
84+
)
85+
}
86+
.launchIn(coroutineScope)
87+
}
88+
89+
fun onLikeButtonClick(post: Post) {
90+
updatePostStatus(post = post)
91+
}
92+
7293
override fun onClick(post: Post) {
94+
post.displayCount++
95+
updatePostStatus(post)
7396
_goToDetailScreen.value = Event(post)
7497
}
7598
}

‎app/src/main/res/layout/row_post.xml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
android:layout_width="20dp"
8282
android:layout_height="20dp"
8383
android:layout_marginEnd="16dp"
84+
favoriteImageSrc="@{item.isFavorite}"
8485
android:padding="2dp"
8586
android:background="#00ffffff"
8687
android:src="@drawable/ic_outline_thumb_up_24"

‎buildSrc/src/main/java/extension/DependencyHandlerExtension.kt‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,12 @@ fun DependencyHandler.addBaseDynamicFeatureModuleDependencies() {
131131
implementation(Deps.NAVIGATION_RUNTIME)
132132
implementation(Deps.NAVIGATION_DYNAMIC)
133133

134-
// Dagger
134+
// Dagger Hilt
135135
implementation(Deps.DAGGER_HILT_ANDROID)
136136
kapt(Deps.DAGGER_HILT_COMPILER)
137+
// Dagger Hilt AndroidX & ViewModel
138+
implementation(Deps.DAGGER_HILT_VIEWMODEL)
139+
kapt(Deps.DAGGER_HILT_ANDROIDX_HILT_COMPILER)
137140

138141
// RxJava
139142
implementation(Deps.RX_JAVA3)

‎features/post_detail/build.gradle.kts‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ dependencies {
5858
implementation(project(Modules.APP))
5959
implementation(project(Modules.AndroidLibrary.CORE))
6060
implementation(project(Modules.AndroidLibrary.DOMAIN))
61+
implementation(project(Modules.AndroidLibrary.DATA))
6162

6263
addBaseDynamicFeatureModuleDependencies()
6364

@@ -66,9 +67,6 @@ dependencies {
6667
implementation(Deps.MATERIAL)
6768
implementation(Deps.CONSTRAINT_LAYOUT)
6869

69-
// Lifecycle, LiveData, ViewModel
70-
implementation(Deps.LIFECYCLE_EXTENSIONS)
71-
7270
// Glide
7371
implementation(Deps.GLIDE)
7472
kapt(Deps.GLIDE_COMPILER)

‎features/search/build.gradle.kts‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,6 @@ dependencies {
6666
implementation(Deps.MATERIAL)
6767
implementation(Deps.CONSTRAINT_LAYOUT)
6868

69-
// Lifecycle, LiveData, ViewModel
70-
implementation(Deps.LIFECYCLE_EXTENSIONS)
71-
7269
// Glide
7370
implementation(Deps.GLIDE)
7471
kapt(Deps.GLIDE_COMPILER)

‎libraries/data/src/main/java/com/smarttoolfactory/data/db/PostDaoRxJava3.kt‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.smarttoolfactory.data.db
33
import androidx.room.Dao
44
import androidx.room.Delete
55
import androidx.room.Insert
6+
import androidx.room.OnConflictStrategy
67
import androidx.room.Query
78
import androidx.room.Update
89
import com.smarttoolfactory.data.model.PostEntity
@@ -14,10 +15,10 @@ import io.reactivex.rxjava3.core.Single
1415
@Dao
1516
interface PostDaoRxJava3 {
1617

17-
@Insert
18+
@Insert(onConflict =OnConflictStrategy.REPLACE)
1819
fun insert(postEntity: PostEntity): Completable
1920

20-
@Insert
21+
@Insert(onConflict =OnConflictStrategy.REPLACE)
2122
fun insert(postEntityList: List<PostEntity>): Completable
2223

2324
@Delete

‎libraries/data/src/main/java/com/smarttoolfactory/data/db/PostStatusDao.kt‎

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package com.smarttoolfactory.data.db
22

33
import androidx.room.Dao
44
import androidx.room.Embedded
5+
import androidx.room.Insert
6+
import androidx.room.OnConflictStrategy
57
import androidx.room.Query
68
import androidx.room.Relation
79
import androidx.room.Transaction
@@ -15,8 +17,14 @@ interface PostStatusDao {
1517
/**
1618
* Update a post's favorite or display count status.
1719
*/
18-
// @Update
19-
// suspend fun updatePostStatus(postStatus: PostStatus)
20+
@Insert(onConflict = OnConflictStrategy.REPLACE)
21+
suspend fun insertOrUpdatePostStatus(postStatus: PostStatus)
22+
23+
/**
24+
* Get status belong to current user for this [PostEntity] with [PostEntity.id]
25+
*/
26+
@Query("SELECT * FROM post_status WHERE userAccountId =:userId AND postId =:postId")
27+
suspend fun getUpdateStatus(userId: Int, postId: Int): PostStatus?
2028

2129
/**
2230
* This method uses [Embedded] and [Relation] annotations to create a class that contains

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /