Fix scroll to bottom button visibility (#1219)

This commit is contained in:
Andrew 2023-05-30 11:44:20 +09:30 committed by GitHub
parent 22ed2dd8aa
commit e8d26222b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 29 additions and 20 deletions

View File

@ -21,7 +21,6 @@ import android.widget.Toast
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.annotation.DimenRes import androidx.annotation.DimenRes
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.core.view.isGone
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
@ -210,6 +209,8 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
val searchViewModel: SearchViewModel by viewModels() val searchViewModel: SearchViewModel by viewModels()
var searchViewItem: MenuItem? = null var searchViewItem: MenuItem? = null
private var emojiPickerVisible = false
private val isScrolledToBottom: Boolean private val isScrolledToBottom: Boolean
get() = binding?.conversationRecyclerView?.isScrolledToBottom ?: true get() = binding?.conversationRecyclerView?.isScrolledToBottom ?: true
@ -441,17 +442,22 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
handleRecyclerViewScrolled() handleRecyclerViewScrolled()
} }
}) })
binding!!.conversationRecyclerView.addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ ->
showScrollToBottomButtonIfApplicable()
}
} }
// called from onCreate // called from onCreate
private fun setUpToolBar() { private fun setUpToolBar() {
setSupportActionBar(binding?.toolbar) val binding = binding ?: return
setSupportActionBar(binding.toolbar)
val actionBar = supportActionBar ?: return val actionBar = supportActionBar ?: return
val recipient = viewModel.recipient ?: return val recipient = viewModel.recipient ?: return
actionBar.title = "" actionBar.title = ""
actionBar.setDisplayHomeAsUpEnabled(true) actionBar.setDisplayHomeAsUpEnabled(true)
actionBar.setHomeButtonEnabled(true) actionBar.setHomeButtonEnabled(true)
binding!!.toolbarContent.conversationTitleView.text = when { binding.toolbarContent.conversationTitleView.text = when {
recipient.isLocalNumber -> getString(R.string.note_to_self) recipient.isLocalNumber -> getString(R.string.note_to_self)
else -> recipient.toShortString() else -> recipient.toShortString()
} }
@ -461,13 +467,11 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
R.dimen.small_profile_picture_size R.dimen.small_profile_picture_size
} }
val size = resources.getDimension(sizeID).roundToInt() val size = resources.getDimension(sizeID).roundToInt()
binding!!.toolbarContent.profilePictureView.root.layoutParams = LinearLayout.LayoutParams(size, size) binding.toolbarContent.profilePictureView.root.layoutParams = LinearLayout.LayoutParams(size, size)
binding!!.toolbarContent.profilePictureView.root.glide = glide binding.toolbarContent.profilePictureView.root.glide = glide
MentionManagerUtilities.populateUserPublicKeyCacheIfNeeded(viewModel.threadId, this) MentionManagerUtilities.populateUserPublicKeyCacheIfNeeded(viewModel.threadId, this)
val profilePictureView = binding!!.toolbarContent.profilePictureView.root val profilePictureView = binding.toolbarContent.profilePictureView.root
viewModel.recipient?.let { recipient -> viewModel.recipient?.let(profilePictureView::update)
profilePictureView.update(recipient)
}
} }
// called from onCreate // called from onCreate
@ -904,15 +908,14 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
val binding = binding ?: return val binding = binding ?: return
val wasTypingIndicatorVisibleBefore = binding.typingIndicatorViewContainer.isVisible val wasTypingIndicatorVisibleBefore = binding.typingIndicatorViewContainer.isVisible
binding.typingIndicatorViewContainer.isVisible = wasTypingIndicatorVisibleBefore && isScrolledToBottom binding.typingIndicatorViewContainer.isVisible = wasTypingIndicatorVisibleBefore && isScrolledToBottom
binding.typingIndicatorViewContainer.isVisible showScrollToBottomButtonIfApplicable()
showOrHidScrollToBottomButton()
val firstVisiblePosition = layoutManager?.findFirstVisibleItemPosition() ?: -1 val firstVisiblePosition = layoutManager?.findFirstVisibleItemPosition() ?: -1
unreadCount = min(unreadCount, firstVisiblePosition).coerceAtLeast(0) unreadCount = min(unreadCount, firstVisiblePosition).coerceAtLeast(0)
updateUnreadCountIndicator() updateUnreadCountIndicator()
} }
private fun showOrHidScrollToBottomButton(show: Boolean = true) { private fun showScrollToBottomButtonIfApplicable() {
binding?.scrollToBottomButton?.isVisible = show && !isScrolledToBottom && adapter.itemCount > 0 binding?.scrollToBottomButton?.isVisible = !emojiPickerVisible && !isScrolledToBottom && adapter.itemCount > 0
} }
private fun updateUnreadCountIndicator() { private fun updateUnreadCountIndicator() {
@ -1084,21 +1087,26 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
Log.e("Loki", "Failed to show emoji picker", e) Log.e("Loki", "Failed to show emoji picker", e)
return return
} }
val binding = binding ?: return
emojiPickerVisible = true
ViewUtil.hideKeyboard(this, visibleMessageView) ViewUtil.hideKeyboard(this, visibleMessageView)
binding?.reactionsShade?.isVisible = true binding.reactionsShade.isVisible = true
showOrHidScrollToBottomButton(false) binding.scrollToBottomButton.isVisible = false
binding?.conversationRecyclerView?.suppressLayout(true) binding.conversationRecyclerView.suppressLayout(true)
reactionDelegate.setOnActionSelectedListener(ReactionsToolbarListener(message)) reactionDelegate.setOnActionSelectedListener(ReactionsToolbarListener(message))
reactionDelegate.setOnHideListener(object: ConversationReactionOverlay.OnHideListener { reactionDelegate.setOnHideListener(object: ConversationReactionOverlay.OnHideListener {
override fun startHide() { override fun startHide() {
binding?.reactionsShade?.let { emojiPickerVisible = false
binding.reactionsShade.let {
ViewUtil.fadeOut(it, resources.getInteger(R.integer.reaction_scrubber_hide_duration), View.GONE) ViewUtil.fadeOut(it, resources.getInteger(R.integer.reaction_scrubber_hide_duration), View.GONE)
} }
showOrHidScrollToBottomButton(true) showScrollToBottomButtonIfApplicable()
} }
override fun onHide() { override fun onHide() {
binding?.conversationRecyclerView?.suppressLayout(false) binding.conversationRecyclerView.suppressLayout(false)
WindowUtil.setLightStatusBarFromTheme(this@ConversationActivityV2); WindowUtil.setLightStatusBarFromTheme(this@ConversationActivityV2);
WindowUtil.setLightNavigationBarFromTheme(this@ConversationActivityV2); WindowUtil.setLightNavigationBarFromTheme(this@ConversationActivityV2);

View File

@ -5,6 +5,7 @@ import android.util.TypedValue
import androidx.annotation.AttrRes import androidx.annotation.AttrRes
import androidx.annotation.ColorInt import androidx.annotation.ColorInt
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import kotlin.math.max
@ColorInt @ColorInt
fun Context.getColorFromAttr( fun Context.getColorFromAttr(
@ -17,4 +18,4 @@ fun Context.getColorFromAttr(
} }
val RecyclerView.isScrolledToBottom: Boolean val RecyclerView.isScrolledToBottom: Boolean
get() = computeVerticalScrollOffset() + computeVerticalScrollExtent() >= computeVerticalScrollRange() get() = max(0, computeVerticalScrollOffset()) + computeVerticalScrollExtent() >= computeVerticalScrollRange()