Skip to content

Commit dcb6642

Browse files
authored
courses: smoother list payloads diffing (fixes #8994) (#8960)
1 parent fec5226 commit dcb6642

File tree

3 files changed

+68
-27
lines changed

3 files changed

+68
-27
lines changed

app/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ android {
99
applicationId "org.ole.planet.myplanet"
1010
minSdk = 26
1111
targetSdk = 36
12-
versionCode = 3710
13-
versionName = "0.37.10"
12+
versionCode = 3711
13+
versionName = "0.37.11"
1414
ndkVersion = '26.3.11579264'
1515
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
1616
vectorDrawables.useSupportLibrary = true

app/src/main/java/org/ole/planet/myplanet/ui/courses/AdapterCourses.kt

Lines changed: 64 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ class AdapterCourses(
6161

6262
companion object {
6363
private const val TAG_PAYLOAD = "payload_tags"
64+
private const val RATING_PAYLOAD = "payload_rating"
65+
private const val PROGRESS_PAYLOAD = "payload_progress"
6466
}
6567

6668
init {
@@ -84,13 +86,28 @@ class AdapterCourses(
8486
newList,
8587
areItemsTheSame = { old, new -> old?.id == new?.id },
8688
areContentsTheSame = { old, new ->
89+
val ratingSame = map[old?.courseId] == map[new?.courseId]
90+
val progressSame = progressMap?.get(old?.courseId) == progressMap?.get(new?.courseId)
91+
8792
old?.courseTitle == new?.courseTitle &&
8893
old?.description == new?.description &&
8994
old?.gradeLevel == new?.gradeLevel &&
9095
old?.subjectLevel == new?.subjectLevel &&
9196
old?.createdDate == new?.createdDate &&
9297
old?.isMyCourse == new?.isMyCourse &&
93-
old?.getNumberOfSteps() == new?.getNumberOfSteps()
98+
old?.getNumberOfSteps() == new?.getNumberOfSteps() &&
99+
ratingSame &&
100+
progressSame
101+
},
102+
getChangePayload = { old, new ->
103+
val bundle = Bundle()
104+
if (map[old?.courseId] != map[new?.courseId]) {
105+
bundle.putBoolean(RATING_PAYLOAD, true)
106+
}
107+
if (progressMap?.get(old?.courseId) != progressMap?.get(new?.courseId)) {
108+
bundle.putBoolean(PROGRESS_PAYLOAD, true)
109+
}
110+
if (bundle.isEmpty) null else bundle
94111
}
95112
)
96113
courseList = newList
@@ -176,7 +193,8 @@ class AdapterCourses(
176193
if (!isGuest) setupRatingBar(holder, course)
177194
setupCheckbox(holder, course, position, isGuest)
178195

179-
showProgressAndRating(position, holder)
196+
updateRatingViews(holder, position)
197+
updateProgressViews(holder, position)
180198

181199
holder.rowCourseBinding.root.setOnClickListener {
182200
val newPosition = holder.bindingAdapterPosition
@@ -313,10 +331,28 @@ class AdapterCourses(
313331
position: Int,
314332
payloads: MutableList<Any>
315333
) {
316-
if (holder is ViewHoldercourse && payloads.any { it == TAG_PAYLOAD }) {
317-
val courseId = courseList.getOrNull(position)?.id ?: return
318-
val tags = tagCache[courseId].orEmpty()
319-
renderTagCloud(holder.rowCourseBinding.flexboxDrawable, tags)
334+
if (holder !is ViewHoldercourse) {
335+
super.onBindViewHolder(holder, position, payloads)
336+
return
337+
}
338+
339+
val hasTagPayload = payloads.any { it == TAG_PAYLOAD }
340+
val bundle = payloads.filterIsInstance<Bundle>().fold(Bundle()) { acc, b -> acc.apply { putAll(b) } }
341+
val hasRatingPayload = bundle.containsKey(RATING_PAYLOAD)
342+
val hasProgressPayload = bundle.containsKey(PROGRESS_PAYLOAD)
343+
344+
if (hasTagPayload || hasRatingPayload || hasProgressPayload) {
345+
if (hasTagPayload) {
346+
val courseId = courseList.getOrNull(position)?.id ?: return
347+
val tags = tagCache[courseId].orEmpty()
348+
renderTagCloud(holder.rowCourseBinding.flexboxDrawable, tags)
349+
}
350+
if (hasRatingPayload) {
351+
updateRatingViews(holder, position)
352+
}
353+
if (hasProgressPayload) {
354+
updateProgressViews(holder, position)
355+
}
320356
} else {
321357
super.onBindViewHolder(holder, position, payloads)
322358
}
@@ -374,34 +410,37 @@ class AdapterCourses(
374410
}
375411
}
376412

377-
private fun showProgressAndRating(position: Int, holder: RecyclerView.ViewHolder) {
378-
val viewHolder = holder as ViewHoldercourse
379-
showProgress(viewHolder.rowCourseBinding, position)
380-
if (map.containsKey(courseList[position]!!.courseId)) {
381-
val `object` = map[courseList[position]!!.courseId]
413+
private fun updateRatingViews(holder: ViewHoldercourse, position: Int) {
414+
val course = courseList.getOrNull(position) ?: return
415+
if (map.containsKey(course.courseId)) {
416+
val ratingObject = map[course.courseId]
382417
CourseRatingUtils.showRating(
383418
context,
384-
`object`,
385-
viewHolder.rowCourseBinding.rating,
386-
viewHolder.rowCourseBinding.timesRated,
387-
viewHolder.rowCourseBinding.ratingBar
419+
ratingObject,
420+
holder.rowCourseBinding.rating,
421+
holder.rowCourseBinding.timesRated,
422+
holder.rowCourseBinding.ratingBar
388423
)
389424
} else {
390-
viewHolder.rowCourseBinding.ratingBar.rating = 0f
425+
holder.rowCourseBinding.ratingBar.rating = 0f
426+
holder.rowCourseBinding.rating.text = context.getString(R.string.zero_point_zero)
427+
holder.rowCourseBinding.timesRated.text = context.getString(R.string.rating_count_format, 0)
391428
}
392429
}
393430

394-
private fun showProgress(binding: RowCourseBinding, position: Int) {
395-
if (progressMap?.containsKey(courseList[position]?.courseId) == true) {
396-
val ob = progressMap!![courseList[position]?.courseId]
397-
binding.courseProgress.max = getInt("max", ob)
398-
binding.courseProgress.progress = getInt("current", ob)
399-
if (getInt("current", ob) < getInt("max", ob)) {
400-
binding.courseProgress.secondaryProgress = getInt("current", ob) + 1
431+
private fun updateProgressViews(holder: ViewHoldercourse, position: Int) {
432+
val course = courseList.getOrNull(position) ?: return
433+
val progress = progressMap?.get(course.courseId)
434+
if (progress != null) {
435+
holder.rowCourseBinding.courseProgress.max = getInt("max", progress)
436+
val currentProgress = getInt("current", progress)
437+
holder.rowCourseBinding.courseProgress.progress = currentProgress
438+
if (currentProgress < holder.rowCourseBinding.courseProgress.max) {
439+
holder.rowCourseBinding.courseProgress.secondaryProgress = currentProgress + 1
401440
}
402-
binding.courseProgress.visibility = View.VISIBLE
441+
holder.rowCourseBinding.courseProgress.visibility = View.VISIBLE
403442
} else {
404-
binding.courseProgress.visibility = View.GONE
443+
holder.rowCourseBinding.courseProgress.visibility = View.GONE
405444
}
406445
}
407446

app/src/main/java/org/ole/planet/myplanet/utilities/DiffUtils.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,10 @@ object DiffUtils {
2525
override fun getNewListSize() = newList.size
2626
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int) =
2727
areItemsTheSame(oldList[oldItemPosition], newList[newItemPosition])
28+
2829
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int) =
2930
areContentsTheSame(oldList[oldItemPosition], newList[newItemPosition])
31+
3032
override fun getChangePayload(oldItemPosition: Int, newItemPosition: Int): Any? {
3133
return getChangePayload?.invoke(oldList[oldItemPosition], newList[newItemPosition])
3234
}

0 commit comments

Comments
 (0)