mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-23 04:28:35 +00:00
Fix scroll to bottom on send bug in CFv2.
This commit is contained in:
@@ -8,6 +8,7 @@ import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.rxjava3.core.Observable
|
||||
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||
import io.reactivex.rxjava3.disposables.Disposable
|
||||
import io.reactivex.rxjava3.kotlin.addTo
|
||||
import io.reactivex.rxjava3.kotlin.plusAssign
|
||||
import io.reactivex.rxjava3.kotlin.subscribeBy
|
||||
import io.reactivex.rxjava3.subjects.BehaviorSubject
|
||||
@@ -27,7 +28,7 @@ class ScrollToPositionDelegate private constructor(
|
||||
private val recyclerView: RecyclerView,
|
||||
canJumpToPosition: (Int) -> Boolean,
|
||||
mapToTruePosition: (Int) -> Int,
|
||||
disposables: CompositeDisposable
|
||||
private val disposables: CompositeDisposable
|
||||
) : Disposable by disposables {
|
||||
companion object {
|
||||
private val TAG = Log.tag(ScrollToPositionDelegate::class.java)
|
||||
@@ -41,10 +42,12 @@ class ScrollToPositionDelegate private constructor(
|
||||
)
|
||||
}
|
||||
|
||||
private val listCommitted = BehaviorSubject.create<Unit>()
|
||||
private val listCommitted = BehaviorSubject.create<Long>()
|
||||
private val scrollPositionRequested = BehaviorSubject.createDefault(EMPTY)
|
||||
private val scrollPositionRequests: Observable<ScrollToPositionRequest> = Observable.combineLatest(listCommitted, scrollPositionRequested) { _, b -> b }
|
||||
|
||||
private var markedListCommittedTimestamp: Long = 0L
|
||||
|
||||
constructor(
|
||||
recyclerView: RecyclerView,
|
||||
canJumpToPosition: (Int) -> Boolean = { true },
|
||||
@@ -91,16 +94,37 @@ class ScrollToPositionDelegate private constructor(
|
||||
requestScrollPosition(0, true)
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the scroll position to 0 after a list update is committed that occurs later
|
||||
* than the version set by [markListCommittedVersion].
|
||||
*/
|
||||
@AnyThread
|
||||
fun resetScrollPositionAfterMarkListVersionSurpassed() {
|
||||
val currentMark = markedListCommittedTimestamp
|
||||
listCommitted
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.filter { it > currentMark }
|
||||
.firstElement()
|
||||
.subscribeBy {
|
||||
requestScrollPosition(0, true)
|
||||
}
|
||||
.addTo(disposables)
|
||||
}
|
||||
|
||||
/**
|
||||
* This should be called every time a list is submitted to the RecyclerView's adapter.
|
||||
*/
|
||||
@AnyThread
|
||||
fun notifyListCommitted() {
|
||||
listCommitted.onNext(Unit)
|
||||
listCommitted.onNext(System.currentTimeMillis())
|
||||
}
|
||||
|
||||
fun isListCommitted(): Boolean = listCommitted.value != null
|
||||
|
||||
fun markListCommittedVersion() {
|
||||
markedListCommittedTimestamp = listCommitted.value ?: 0L
|
||||
}
|
||||
|
||||
private fun handleScrollPositionRequest(
|
||||
request: ScrollToPositionRequest,
|
||||
recyclerView: RecyclerView
|
||||
|
||||
@@ -1679,6 +1679,7 @@ class ConversationFragment :
|
||||
)
|
||||
|
||||
disposables += send
|
||||
.doOnSubscribe { scrollToPositionDelegate.markListCommittedVersion() }
|
||||
.subscribeBy(
|
||||
onError = { t ->
|
||||
Log.w(TAG, "Error sending", t)
|
||||
@@ -1710,7 +1711,7 @@ class ConversationFragment :
|
||||
|
||||
conversationItemDecorations.unreadCount = 0
|
||||
|
||||
scrollToPositionDelegate.resetScrollPosition()
|
||||
scrollToPositionDelegate.resetScrollPositionAfterMarkListVersionSurpassed()
|
||||
attachmentManager.cleanup()
|
||||
|
||||
updateLinkPreviewState()
|
||||
|
||||
@@ -320,7 +320,7 @@
|
||||
android:layout_marginHorizontal="16dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="@id/navigation_bar_guideline"
|
||||
app:layout_constraintBottom_toBottomOf="@id/keyboard_guideline"
|
||||
app:layout_constraintEnd_toEndOf="@+id/parent_end_guideline"
|
||||
app:layout_constraintStart_toStartOf="@+id/parent_start_guideline" />
|
||||
|
||||
|
||||
Reference in New Issue
Block a user