diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/reply/group/StoryGroupReplyFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/reply/group/StoryGroupReplyFragment.kt index 38e5948da6..f5869682cf 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/reply/group/StoryGroupReplyFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/reply/group/StoryGroupReplyFragment.kt @@ -10,6 +10,9 @@ import android.widget.Toast import androidx.annotation.ColorInt import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.google.android.material.bottomsheet.BottomSheetBehaviorHack @@ -17,6 +20,7 @@ import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.dialog.MaterialAlertDialogBuilder import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.kotlin.subscribeBy +import kotlinx.coroutines.launch import org.signal.core.util.concurrent.LifecycleDisposable import org.signal.core.util.concurrent.SignalExecutors import org.signal.core.util.getParcelableCompat @@ -190,31 +194,33 @@ class StoryGroupReplyFragment : var firstSubmit = true - lifecycleDisposable += viewModel.state - .observeOn(AndroidSchedulers.mainThread()) - .subscribeBy { state -> - if (markReadHelper == null && state.threadId > 0L) { - if (isResumed) { - ApplicationDependencies.getMessageNotifier().setVisibleThread(ConversationId(state.threadId, storyId)) + lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.RESUMED) { + viewModel.state.collect { state -> + if (markReadHelper == null && state.threadId > 0L) { + if (isResumed) { + ApplicationDependencies.getMessageNotifier().setVisibleThread(ConversationId(state.threadId, storyId)) + } + + markReadHelper = MarkReadHelper(ConversationId(state.threadId, storyId), requireContext(), viewLifecycleOwner) + + if (isFromNotification) { + markReadHelper?.onViewsRevealed(System.currentTimeMillis()) + } } - markReadHelper = MarkReadHelper(ConversationId(state.threadId, storyId), requireContext(), viewLifecycleOwner) + emptyNotice.visible = state.noReplies && state.loadState == StoryGroupReplyState.LoadState.READY + colorizer.onNameColorsChanged(state.nameColors) - if (isFromNotification) { - markReadHelper?.onViewsRevealed(System.currentTimeMillis()) - } - } - - emptyNotice.visible = state.noReplies && state.loadState == StoryGroupReplyState.LoadState.READY - colorizer.onNameColorsChanged(state.nameColors) - - adapter.submitList(getConfiguration(state.replies).toMappingModelList()) { - if (firstSubmit && (groupReplyStartPosition >= 0 && adapter.hasItem(groupReplyStartPosition))) { - firstSubmit = false - recyclerView.post { recyclerView.scrollToPosition(groupReplyStartPosition) } + adapter.submitList(getConfiguration(state.replies).toMappingModelList()) { + if (firstSubmit && (groupReplyStartPosition >= 0 && adapter.hasItem(groupReplyStartPosition))) { + firstSubmit = false + recyclerView.post { recyclerView.scrollToPosition(groupReplyStartPosition) } + } } } } + } dataObserver = GroupDataObserver() adapter.registerAdapterDataObserver(dataObserver) diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/reply/group/StoryGroupReplyViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/reply/group/StoryGroupReplyViewModel.kt index e7a51bfe50..7145e86006 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/reply/group/StoryGroupReplyViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/reply/group/StoryGroupReplyViewModel.kt @@ -3,21 +3,22 @@ package org.thoughtcrime.securesms.stories.viewer.reply.group import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers -import io.reactivex.rxjava3.core.Flowable import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.plusAssign import io.reactivex.rxjava3.kotlin.subscribeBy +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.update import org.signal.paging.ProxyPagingController import org.thoughtcrime.securesms.database.model.MessageId -import org.thoughtcrime.securesms.util.rx.RxStore class StoryGroupReplyViewModel(storyId: Long, repository: StoryGroupReplyRepository) : ViewModel() { - private val store = RxStore(StoryGroupReplyState()) + private val store = MutableStateFlow(StoryGroupReplyState()) private val disposables = CompositeDisposable() - val stateSnapshot: StoryGroupReplyState = store.state - val state: Flowable = store.stateFlowable + val stateSnapshot: StoryGroupReplyState get() = store.value + val state: Flow = store val pagingController: ProxyPagingController = ProxyPagingController() @@ -49,7 +50,6 @@ class StoryGroupReplyViewModel(storyId: Long, repository: StoryGroupReplyReposit override fun onCleared() { disposables.clear() - store.dispose() } class Factory(private val storyId: Long, private val repository: StoryGroupReplyRepository) : ViewModelProvider.Factory {