From 25bf865514ba59a4ce85389020d76a8c3db3228c Mon Sep 17 00:00:00 2001 From: mtgriego Date: Tue, 27 Aug 2024 11:20:35 -0700 Subject: [PATCH] remove rx1 from message thread holder/viewmodel (#2111) --- .../ui/viewholders/MessageThreadViewHolder.kt | 60 ++++++++++--------- .../MessageThreadHolderViewModel.kt | 37 +++++++----- .../MessageThreadHolderViewModelTest.kt | 27 +++++---- 3 files changed, 70 insertions(+), 54 deletions(-) diff --git a/app/src/main/java/com/kickstarter/ui/viewholders/MessageThreadViewHolder.kt b/app/src/main/java/com/kickstarter/ui/viewholders/MessageThreadViewHolder.kt index 8ea3c208cd..4d9d03edf8 100644 --- a/app/src/main/java/com/kickstarter/ui/viewholders/MessageThreadViewHolder.kt +++ b/app/src/main/java/com/kickstarter/ui/viewholders/MessageThreadViewHolder.kt @@ -2,25 +2,27 @@ package com.kickstarter.ui.viewholders import android.content.Intent import android.graphics.Typeface +import android.view.View import android.widget.TextView -import com.jakewharton.rxbinding.view.RxView import com.kickstarter.R import com.kickstarter.databinding.MessageThreadViewBinding import com.kickstarter.libs.MessagePreviousScreenType import com.kickstarter.libs.rx.transformers.Transformers import com.kickstarter.libs.utils.DateTimeUtils -import com.kickstarter.libs.utils.ViewUtils +import com.kickstarter.libs.utils.extensions.addToDisposable import com.kickstarter.libs.utils.extensions.wrapInParentheses import com.kickstarter.models.MessageThread import com.kickstarter.ui.IntentKey import com.kickstarter.ui.activities.MessagesActivity import com.kickstarter.ui.extensions.loadCircleImage import com.kickstarter.viewmodels.MessageThreadHolderViewModel +import io.reactivex.disposables.CompositeDisposable import org.joda.time.DateTime class MessageThreadViewHolder(private val binding: MessageThreadViewBinding) : KSViewHolder(binding.root) { private val viewModel = MessageThreadHolderViewModel.ViewModel(environment()) private val ksString = requireNotNull(environment().ksString()) + private val disposables = CompositeDisposable() @Throws(Exception::class) override fun bindData(data: Any?) { @@ -54,49 +56,53 @@ class MessageThreadViewHolder(private val binding: MessageThreadViewBinding) : K } init { - RxView.clicks(binding.messageThreadContainer) - .compose(bindToLifecycle()) - .compose(Transformers.observeForUI()) - .subscribe { viewModel.inputs.messageThreadCardViewClicked() } + binding.messageThreadContainer.setOnClickListener { + viewModel.inputs.messageThreadCardViewClicked() + } viewModel.outputs.dateDateTime() - .compose(bindToLifecycle()) - .compose(Transformers.observeForUI()) + .compose(Transformers.observeForUIV2()) .subscribe { setDateTextView(it) } + .addToDisposable(disposables) viewModel.outputs.dateTextViewIsBold() - .compose(bindToLifecycle()) - .compose(Transformers.observeForUI()) + .compose(Transformers.observeForUIV2()) .subscribe { setTypeface(binding.messageThreadDateTextView, it) } + .addToDisposable(disposables) viewModel.outputs.messageBodyTextViewText() - .compose(bindToLifecycle()) - .compose(Transformers.observeForUI()) + .compose(Transformers.observeForUIV2()) .subscribe { binding.messageThreadBodyTextView.text = it } + .addToDisposable(disposables) viewModel.outputs.messageBodyTextIsBold() - .compose(bindToLifecycle()) - .compose(Transformers.observeForUI()) + .compose(Transformers.observeForUIV2()) .subscribe { setTypeface(binding.messageThreadBodyTextView, it) } + .addToDisposable(disposables) viewModel.outputs.participantAvatarUrl() - .compose(bindToLifecycle()) - .compose(Transformers.observeForUI()) + .compose(Transformers.observeForUIV2()) .subscribe { setParticipantAvatarImageView(it) } + .addToDisposable(disposables) viewModel.outputs.participantNameTextViewIsBold() - .compose(bindToLifecycle()) - .compose(Transformers.observeForUI()) + .compose(Transformers.observeForUIV2()) .subscribe { setTypeface(binding.participantNameTextView, it) } + .addToDisposable(disposables) viewModel.outputs.participantNameTextViewText() - .compose(bindToLifecycle()) - .compose(Transformers.observeForUI()) + .compose(Transformers.observeForUIV2()) .subscribe { binding.participantNameTextView.text = it } + .addToDisposable(disposables) viewModel.outputs.startMessagesActivity() - .compose(bindToLifecycle()) - .compose(Transformers.observeForUI()) + .compose(Transformers.observeForUIV2()) .subscribe { startMessagesActivity(it) } + .addToDisposable(disposables) viewModel.outputs.unreadCountTextViewIsGone() - .compose(bindToLifecycle()) - .compose(Transformers.observeForUI()) - .subscribe(ViewUtils.setGone(binding.messageThreadUnreadCountTextView)) + .compose(Transformers.observeForUIV2()) + .subscribe { binding.messageThreadUnreadCountTextView.visibility = View.GONE } + .addToDisposable(disposables) viewModel.outputs.unreadCountTextViewText() - .compose(bindToLifecycle()) - .compose(Transformers.observeForUI()) + .compose(Transformers.observeForUIV2()) .subscribe { setUnreadCountTextView(it) } + .addToDisposable(disposables) + } + + override fun destroy() { + disposables.clear() + super.destroy() } } diff --git a/app/src/main/java/com/kickstarter/viewmodels/MessageThreadHolderViewModel.kt b/app/src/main/java/com/kickstarter/viewmodels/MessageThreadHolderViewModel.kt index 9fa70a1647..69f8a98d68 100644 --- a/app/src/main/java/com/kickstarter/viewmodels/MessageThreadHolderViewModel.kt +++ b/app/src/main/java/com/kickstarter/viewmodels/MessageThreadHolderViewModel.kt @@ -1,18 +1,18 @@ package com.kickstarter.viewmodels import android.content.SharedPreferences -import com.kickstarter.libs.ActivityViewModel import com.kickstarter.libs.Environment import com.kickstarter.libs.rx.transformers.Transformers import com.kickstarter.libs.utils.NumberUtils +import com.kickstarter.libs.utils.extensions.addToDisposable import com.kickstarter.libs.utils.extensions.isNotNull import com.kickstarter.libs.utils.extensions.negate import com.kickstarter.models.MessageThread import com.kickstarter.ui.SharedPreferenceKey -import com.kickstarter.ui.viewholders.MessageThreadViewHolder +import io.reactivex.Observable +import io.reactivex.disposables.CompositeDisposable +import io.reactivex.subjects.PublishSubject import org.joda.time.DateTime -import rx.Observable -import rx.subjects.PublishSubject interface MessageThreadHolderViewModel { interface Inputs { @@ -58,12 +58,11 @@ interface MessageThreadHolderViewModel { fun unreadCountTextViewText(): Observable } - class ViewModel(environment: Environment) : - ActivityViewModel(environment), Inputs, Outputs { + class ViewModel(val environment: Environment) : androidx.lifecycle.ViewModel(), Inputs, Outputs { private val sharedPreferences: SharedPreferences? - private val messageThread = PublishSubject.create() - private val messageThreadCardViewClicked = PublishSubject.create() + private val messageThread = PublishSubject.create() + private val messageThreadCardViewClicked = PublishSubject.create() private val cardViewIsElevated: Observable private val dateDateTime: Observable private val dateTextViewIsBold: Observable @@ -78,19 +77,21 @@ interface MessageThreadHolderViewModel { val inputs: Inputs = this val outputs: Outputs = this + val disposables = CompositeDisposable() init { sharedPreferences = requireNotNull(environment.sharedPreferences()) // Store the correct initial hasUnreadMessages value. messageThread - .compose(Transformers.observeForUI()) + .compose(Transformers.observeForUIV2()) + .filter { it.isNotNull() } .subscribe { thread: MessageThread -> setHasUnreadMessagesPreference( thread, sharedPreferences ) - } + }.addToDisposable(disposables) val hasUnreadMessages = Observable.merge( messageThread.map { thread: MessageThread -> @@ -104,11 +105,11 @@ interface MessageThreadHolderViewModel { val lastMessage = messageThread.map { it.lastMessage() } .filter { it.isNotNull() } - .map { requireNotNull(it) } + .map { it } val participant = messageThread.map { it.participant() } .filter { it.isNotNull() } - .map { requireNotNull(it) } + .map { it } cardViewIsElevated = hasUnreadMessages @@ -127,7 +128,7 @@ interface MessageThreadHolderViewModel { participantNameTextViewText = participant.map { it.name() } startMessagesActivity = messageThread.compose( - Transformers.takeWhen( + Transformers.takeWhenV2( messageThreadCardViewClicked ) ) @@ -142,8 +143,9 @@ interface MessageThreadHolderViewModel { } messageThread - .compose(Transformers.takeWhen(messageThreadCardViewClicked)) + .compose(Transformers.takeWhenV2(messageThreadCardViewClicked)) .subscribe { markedAsRead(it, sharedPreferences) } + .addToDisposable(disposables) } override fun configureWith(messageThread: MessageThread) { @@ -151,7 +153,7 @@ interface MessageThreadHolderViewModel { } override fun messageThreadCardViewClicked() { - messageThreadCardViewClicked.onNext(null) + messageThreadCardViewClicked.onNext(Unit) } override fun cardViewIsElevated(): Observable = cardViewIsElevated @@ -209,5 +211,10 @@ interface MessageThreadHolderViewModel { editor.apply() } } + + override fun onCleared() { + disposables.clear() + super.onCleared() + } } } diff --git a/app/src/test/java/com/kickstarter/viewmodels/MessageThreadHolderViewModelTest.kt b/app/src/test/java/com/kickstarter/viewmodels/MessageThreadHolderViewModelTest.kt index e4269fbcb3..e893c01bfb 100644 --- a/app/src/test/java/com/kickstarter/viewmodels/MessageThreadHolderViewModelTest.kt +++ b/app/src/test/java/com/kickstarter/viewmodels/MessageThreadHolderViewModelTest.kt @@ -3,11 +3,13 @@ package com.kickstarter.viewmodels import com.kickstarter.KSRobolectricTestCase import com.kickstarter.libs.Environment import com.kickstarter.libs.utils.NumberUtils +import com.kickstarter.libs.utils.extensions.addToDisposable import com.kickstarter.mock.factories.MessageThreadFactory.messageThread import com.kickstarter.models.MessageThread +import io.reactivex.disposables.CompositeDisposable +import io.reactivex.subscribers.TestSubscriber import org.joda.time.DateTime import org.junit.Test -import rx.observers.TestSubscriber class MessageThreadHolderViewModelTest : KSRobolectricTestCase() { @@ -24,20 +26,21 @@ class MessageThreadHolderViewModelTest : KSRobolectricTestCase() { private val startMessagesActivity = TestSubscriber() private val unreadCountTextViewIsGone = TestSubscriber() private val unreadCountTextViewText = TestSubscriber() + private val disposables = CompositeDisposable() private fun setUpEnvironment(env: Environment) { vm = MessageThreadHolderViewModel.ViewModel(env) - vm.outputs.cardViewIsElevated().subscribe(cardViewIsElevated) - vm.outputs.dateDateTime().subscribe(dateDateTime) - vm.outputs.dateTextViewIsBold().subscribe(dateTextViewIsBold) - vm.outputs.messageBodyTextIsBold().subscribe(messageBodyTextIsBold) - vm.outputs.messageBodyTextViewText().subscribe(messageBodyTextViewText) - vm.outputs.participantAvatarUrl().subscribe(participantAvatarUrl) - vm.outputs.participantNameTextViewIsBold().subscribe(participantNameTextViewIsBold) - vm.outputs.participantNameTextViewText().subscribe(participantNameTextViewText) - vm.outputs.startMessagesActivity().subscribe(startMessagesActivity) - vm.outputs.unreadCountTextViewIsGone().subscribe(unreadCountTextViewIsGone) - vm.outputs.unreadCountTextViewText().subscribe(unreadCountTextViewText) + vm.outputs.cardViewIsElevated().subscribe { cardViewIsElevated.onNext(it) }.addToDisposable(disposables) + vm.outputs.dateDateTime().subscribe { dateDateTime.onNext(it) }.addToDisposable(disposables) + vm.outputs.dateTextViewIsBold().subscribe { dateTextViewIsBold.onNext(it) }.addToDisposable(disposables) + vm.outputs.messageBodyTextIsBold().subscribe { messageBodyTextIsBold.onNext(it) }.addToDisposable(disposables) + vm.outputs.messageBodyTextViewText().subscribe { messageBodyTextViewText.onNext(it) }.addToDisposable(disposables) + vm.outputs.participantAvatarUrl().subscribe { participantAvatarUrl.onNext(it) }.addToDisposable(disposables) + vm.outputs.participantNameTextViewIsBold().subscribe { participantNameTextViewIsBold.onNext(it) }.addToDisposable(disposables) + vm.outputs.participantNameTextViewText().subscribe { participantNameTextViewText.onNext(it) }.addToDisposable(disposables) + vm.outputs.startMessagesActivity().subscribe { startMessagesActivity.onNext(it) }.addToDisposable(disposables) + vm.outputs.unreadCountTextViewIsGone().subscribe { unreadCountTextViewIsGone.onNext(it) }.addToDisposable(disposables) + vm.outputs.unreadCountTextViewText().subscribe { unreadCountTextViewText.onNext(it) }.addToDisposable(disposables) } @Test