11package org.thoughtcrime.securesms.conversation
22
33import android.view.View
4+ import android.view.View.OnLayoutChangeListener
5+ import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
6+ import io.reactivex.rxjava3.core.Observable
7+ import io.reactivex.rxjava3.disposables.Disposable
8+ import io.reactivex.rxjava3.subjects.PublishSubject
49import org.signal.core.util.DimensionUnit
510import org.signal.core.util.logging.Log
611
@@ -11,17 +16,55 @@ import org.signal.core.util.logging.Log
1116 * then put a basic amount of padding on each side so that it looks nice when scrolling
1217 * to either end.
1318 */
14- object AttachmentButtonCenterHelper {
19+ class AttachmentButtonCenterHelper ( val buttonHolder : View , val wrapper : View ) {
1520
16- private val TAG = Log .tag(AttachmentButtonCenterHelper ::class )
17- private val DEFAULT_PADDING = DimensionUnit .DP .toPixels(16f ).toInt()
21+ companion object {
22+ val TAG = Log .tag(AttachmentButtonCenterHelper ::class )
23+ private val DEFAULT_PADDING = DimensionUnit .DP .toPixels(16f ).toInt()
24+ }
25+
26+ /* * The wrapper width is the maximum size of the button holder before scrollbars appear. */
27+ private val wrapperWidthObservable: PublishSubject <Int > = PublishSubject .create()
28+ private val emitNewWrapperWidth = OnLayoutChangeListener { _, left, _, right, _, oldLeft, _, oldRight, _ ->
29+ if (oldRight - oldLeft == right - left)
30+ return @OnLayoutChangeListener
31+ wrapperWidthObservable.onNext(right - left)
32+ }
33+
34+ /* * The "core width" of the button holder is the size of its contents. */
35+ private val coreWidthObservable: PublishSubject <Int > = PublishSubject .create()
36+ private val emitNewCoreWidth = OnLayoutChangeListener { view, left, _, right, _, oldLeft, _, oldRight, _ ->
37+ val newCoreWidth = view.run { width - (paddingLeft + paddingRight) }
38+ coreWidthObservable.onNext(newCoreWidth)
39+ }
40+
41+ private var listener: Disposable ? = null
42+
43+ fun attach () {
44+ wrapper.addOnLayoutChangeListener(emitNewWrapperWidth)
45+ buttonHolder.addOnLayoutChangeListener(emitNewCoreWidth)
46+
47+ listener?.dispose()
48+ listener = Observable .combineLatest(wrapperWidthObservable, coreWidthObservable, ::Pair )
49+ .distinctUntilChanged()
50+ .observeOn(AndroidSchedulers .mainThread())
51+ .subscribe { widths ->
52+ val wrapperWidth = widths.first
53+ val coreWidth = widths.second
54+ Log .d(TAG , " wrapperWidth: $wrapperWidth , coreWidth: $coreWidth " )
55+ recenter(coreWidth, wrapperWidth)
56+ }
57+ }
58+
59+ fun detach () {
60+ wrapper.removeOnLayoutChangeListener(emitNewWrapperWidth)
61+ buttonHolder.removeOnLayoutChangeListener(emitNewCoreWidth)
62+ listener?.dispose()
63+ listener = null
64+ }
1865
19- @Synchronized
20- fun recenter (buttonHolder : View , wrapper : View ) {
21- buttonHolder.measure(View .MeasureSpec .UNSPECIFIED , View .MeasureSpec .UNSPECIFIED )
22- buttonHolder.layout(0 , 0 , buttonHolder.measuredWidth, buttonHolder.measuredHeight)
23- val buttonHolderCoreWidth = buttonHolder.run { width - (paddingLeft + paddingRight) }
24- val extraSpace = wrapper.width - buttonHolderCoreWidth
66+ fun recenter (buttonHolderCoreWidth : Int , wrapperWidth : Int ) {
67+ val extraSpace = wrapperWidth - buttonHolderCoreWidth
2568 val horizontalPadding = if (extraSpace >= 0 )
2669 (extraSpace / 2f ).toInt()
2770 else
0 commit comments