Merge pull request #1990 from Hafizzle/Fiz/part-invite-flash-fix

Refresh notification views without "Flash"
This commit is contained in:
Phillip Thelen 2023-06-01 12:25:01 +02:00 committed by GitHub
commit c88ac55ea3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 41 additions and 8 deletions

View file

@ -45,6 +45,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="?android:listDivider"
android:visibility="invisible"
android:orientation="vertical"
android:showDividers="middle" />
</androidx.core.widget.NestedScrollView>

View file

@ -18,6 +18,7 @@ import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.data.InventoryRepository
import com.habitrpg.android.habitica.data.SocialRepository
import com.habitrpg.android.habitica.databinding.ActivityNotificationsBinding
import com.habitrpg.android.habitica.extensions.fadeInAnimation
import com.habitrpg.android.habitica.models.inventory.QuestContent
import com.habitrpg.android.habitica.ui.viewmodels.NotificationsViewModel
import com.habitrpg.common.habitica.extensions.fromHtml
@ -37,6 +38,7 @@ import com.habitrpg.common.habitica.models.notifications.QuestInvitationData
import com.habitrpg.common.habitica.models.notifications.UnallocatedPointsData
import com.habitrpg.common.habitica.views.PixelArtView
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@ -54,6 +56,7 @@ class NotificationsActivity : BaseActivity(), androidx.swiperefreshlayout.widget
val viewModel: NotificationsViewModel by viewModels()
var inflater: LayoutInflater? = null
val viewTagMap = mutableMapOf<String, View>()
override fun getLayoutResId(): Int = R.layout.activity_notifications
@ -104,8 +107,6 @@ class NotificationsActivity : BaseActivity(), androidx.swiperefreshlayout.widget
private fun setNotifications(notifications: List<Notification>) {
this.notifications = notifications
binding.notificationItems.removeAllViewsInLayout()
if (notifications.isEmpty()) {
displayNoNotificationsView()
} else {
@ -114,9 +115,10 @@ class NotificationsActivity : BaseActivity(), androidx.swiperefreshlayout.widget
}
private fun displayNoNotificationsView() {
binding.notificationItems.removeAllViewsInLayout()
binding.notificationItems.showDividers = LinearLayout.SHOW_DIVIDER_NONE
binding.notificationItems.addView(inflater?.inflate(R.layout.no_notifications, binding.notificationItems, false))
refreshViews(listOf())
}
private fun displayNotificationsListView(notifications: List<Notification>) {
@ -125,6 +127,7 @@ class NotificationsActivity : BaseActivity(), androidx.swiperefreshlayout.widget
binding.notificationItems.addView(
createNotificationsHeaderView(notifications.count())
)
val viewList = arrayListOf<View>()
lifecycleScope.launch(ExceptionHandler.coroutine()) {
notifications.map {
@ -144,17 +147,35 @@ class NotificationsActivity : BaseActivity(), androidx.swiperefreshlayout.widget
}
if (item != null) {
item.tag = it.id
if (binding.notificationItems.findViewWithTag<View>(it.id) == null) {
binding.notificationItems.addView(item)
}
viewList.add(item)
}
}
refreshViews(viewList)
}
}
private fun refreshViews(newItems: List<View>) {
val currentViews = (0 until binding.notificationItems.childCount).map {
binding.notificationItems.getChildAt(it)
}
val viewsToRemove = currentViews - newItems
viewsToRemove.forEach { binding.notificationItems.removeView(it) }
val viewsToAdd = newItems - currentViews
viewsToAdd.forEach {
binding.notificationItems.addView(it)
}
lifecycleScope.launch {
delay(250)
// Unnecessary but looks clean c:
if (binding.notificationItems.visibility != View.VISIBLE) {
binding.notificationItems.fadeInAnimation(200)
}
}
}
private fun createNotificationsHeaderView(notificationCount: Int): View? {
val header = inflater?.inflate(R.layout.notifications_header, binding.notificationItems, false)

View file

@ -1,5 +1,6 @@
package com.habitrpg.android.habitica.extensions
import android.animation.ObjectAnimator
import android.content.Context
import android.view.View
import android.view.ViewTreeObserver
@ -28,3 +29,13 @@ inline fun View.afterMeasured(crossinline f: View.() -> Unit) {
}
})
}
fun View.fadeInAnimation(duration: Long = 500) {
this.alpha = 0f
this.visibility = View.VISIBLE
val fadeInAnimation = ObjectAnimator.ofFloat(this, "alpha", 0f, 1f)
fadeInAnimation.duration = duration
fadeInAnimation.start()
}