From 858c7a7f2ed1f815019c0b15a02ae76e319867a9 Mon Sep 17 00:00:00 2001 From: Alex Hart Date: Fri, 24 Jun 2022 14:14:13 -0300 Subject: [PATCH] Implement "unviewed only" mode for story viewer. --- .../securesms/stories/StoryViewerArgs.kt | 12 ++++++++++-- .../stories/landing/StoriesLandingFragment.kt | 4 +++- .../stories/landing/StoriesLandingViewModel.kt | 8 ++++++-- .../stories/viewer/StoryViewerFragment.kt | 10 +++++++++- .../stories/viewer/StoryViewerPagerAdapter.kt | 11 +++++++++-- .../stories/viewer/StoryViewerRepository.kt | 13 ++++++++++++- .../stories/viewer/StoryViewerViewModel.kt | 5 ++++- .../viewer/page/StoryViewerPageFragment.kt | 9 +++++++-- .../viewer/page/StoryViewerPageRepository.kt | 8 +++++--- .../viewer/page/StoryViewerPageViewModel.kt | 12 +++++++++--- .../thoughtcrime/securesms/util/rx/RxStore.kt | 2 +- .../stories/viewer/StoryViewerViewModelTest.kt | 16 ++++++++-------- .../viewer/page/StoryViewerPageViewModelTest.kt | 15 ++++++++------- 13 files changed, 91 insertions(+), 34 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/StoryViewerArgs.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/StoryViewerArgs.kt index 1c2ccf0e46..9ba6ad2fc5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/StoryViewerArgs.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/StoryViewerArgs.kt @@ -19,7 +19,8 @@ data class StoryViewerArgs( val storyThumbBlur: BlurHash? = null, val recipientIds: List = emptyList(), val isFromNotification: Boolean = false, - val groupReplyStartPosition: Int = -1 + val groupReplyStartPosition: Int = -1, + val isUnviewedOnly: Boolean = false ) : Parcelable { class Builder(private val recipientId: RecipientId, private val isInHiddenStoryMode: Boolean) { @@ -31,6 +32,7 @@ data class StoryViewerArgs( private var recipientIds: List = emptyList() private var isFromNotification: Boolean = false private var groupReplyStartPosition: Int = -1 + private var isUnviewedOnly: Boolean = false fun withStoryId(storyId: Long): Builder { this.storyId = storyId @@ -67,6 +69,11 @@ data class StoryViewerArgs( return this } + fun isUnviewedOnly(isUnviewedOnly: Boolean): Builder { + this.isUnviewedOnly = isUnviewedOnly + return this + } + fun build(): StoryViewerArgs { return StoryViewerArgs( recipientId = recipientId, @@ -77,7 +84,8 @@ data class StoryViewerArgs( storyThumbBlur = storyThumbBlur, recipientIds = recipientIds, isFromNotification = isFromNotification, - groupReplyStartPosition = groupReplyStartPosition + groupReplyStartPosition = groupReplyStartPosition, + isUnviewedOnly = isUnviewedOnly ) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/landing/StoriesLandingFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/landing/StoriesLandingFragment.kt index dc7a181428..b5145ff596 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/landing/StoriesLandingFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/landing/StoriesLandingFragment.kt @@ -35,6 +35,7 @@ import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectFor import org.thoughtcrime.securesms.conversation.ui.error.SafetyNumberChangeDialog import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord import org.thoughtcrime.securesms.database.model.MmsMessageRecord +import org.thoughtcrime.securesms.database.model.StoryViewState import org.thoughtcrime.securesms.main.Material3OnScrollHelperBinder import org.thoughtcrime.securesms.mediasend.v2.MediaSelectionActivity import org.thoughtcrime.securesms.permissions.Permissions @@ -237,7 +238,8 @@ class StoriesLandingFragment : DSLSettingsFragment(layoutId = R.layout.stories_l storyThumbTextModel = text, storyThumbUri = image, storyThumbBlur = blur, - recipientIds = viewModel.getRecipientIds(model.data.isHidden) + recipientIds = viewModel.getRecipientIds(model.data.isHidden, model.data.storyViewState == StoryViewState.UNVIEWED), + isUnviewedOnly = model.data.storyViewState == StoryViewState.UNVIEWED ) ), options.toBundle() diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/landing/StoriesLandingViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/landing/StoriesLandingViewModel.kt index e14e119d11..b21cde4581 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/landing/StoriesLandingViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/landing/StoriesLandingViewModel.kt @@ -7,6 +7,7 @@ import io.reactivex.rxjava3.core.Completable import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.plusAssign import org.thoughtcrime.securesms.database.model.MessageRecord +import org.thoughtcrime.securesms.database.model.StoryViewState import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.recipients.RecipientId import org.thoughtcrime.securesms.util.livedata.Store @@ -46,8 +47,11 @@ class StoriesLandingViewModel(private val storiesLandingRepository: StoriesLandi store.update { it.copy(isHiddenContentVisible = isExpanded) } } - fun getRecipientIds(hidden: Boolean): List { - return store.state.storiesLandingItems.filter { it.isHidden == hidden }.map { it.storyRecipient.id } + fun getRecipientIds(hidden: Boolean, isUnviewed: Boolean): List { + return store.state.storiesLandingItems + .filter { it.isHidden == hidden } + .filter { if (isUnviewed) it.storyViewState == StoryViewState.UNVIEWED else true } + .map { it.storyRecipient.id } } class Factory(private val storiesLandingRepository: StoriesLandingRepository) : ViewModelProvider.Factory { diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/StoryViewerFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/StoryViewerFragment.kt index 96b77b5913..5cf59b6579 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/StoryViewerFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/StoryViewerFragment.kt @@ -34,8 +34,16 @@ class StoryViewerFragment : Fragment(R.layout.stories_viewer_fragment), StoryVie override fun onViewCreated(view: View, savedInstanceState: Bundle?) { storyPager = view.findViewById(R.id.story_item_pager) - val adapter = StoryViewerPagerAdapter(this, storyViewerArgs.storyId, storyViewerArgs.isFromNotification, storyViewerArgs.groupReplyStartPosition) + val adapter = StoryViewerPagerAdapter( + this, + storyViewerArgs.storyId, + storyViewerArgs.isFromNotification, + storyViewerArgs.groupReplyStartPosition, + storyViewerArgs.isUnviewedOnly + ) + storyPager.adapter = adapter + storyPager.overScrollMode = ViewPager2.OVER_SCROLL_NEVER viewModel.isChildScrolling.observe(viewLifecycleOwner) { storyPager.isUserInputEnabled = !it diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/StoryViewerPagerAdapter.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/StoryViewerPagerAdapter.kt index d93c313286..8549ca8569 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/StoryViewerPagerAdapter.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/StoryViewerPagerAdapter.kt @@ -2,6 +2,7 @@ package org.thoughtcrime.securesms.stories.viewer import androidx.fragment.app.Fragment import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.RecyclerView import androidx.viewpager2.adapter.FragmentStateAdapter import org.thoughtcrime.securesms.recipients.RecipientId import org.thoughtcrime.securesms.stories.viewer.page.StoryViewerPageFragment @@ -10,7 +11,8 @@ class StoryViewerPagerAdapter( fragment: Fragment, private val initialStoryId: Long, private val isFromNotification: Boolean, - private val groupReplyStartPosition: Int + private val groupReplyStartPosition: Int, + private val isUnviewedOnly: Boolean ) : FragmentStateAdapter(fragment) { private var pages: List = emptyList() @@ -23,10 +25,15 @@ class StoryViewerPagerAdapter( DiffUtil.calculateDiff(callback).dispatchUpdatesTo(this) } + override fun onAttachedToRecyclerView(recyclerView: RecyclerView) { + super.onAttachedToRecyclerView(recyclerView) + recyclerView.overScrollMode = RecyclerView.OVER_SCROLL_NEVER + } + override fun getItemCount(): Int = pages.size override fun createFragment(position: Int): Fragment { - return StoryViewerPageFragment.create(pages[position], initialStoryId, isFromNotification, groupReplyStartPosition) + return StoryViewerPageFragment.create(pages[position], initialStoryId, isFromNotification, groupReplyStartPosition, isUnviewedOnly) } private class Callback( diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/StoryViewerRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/StoryViewerRepository.kt index 425272c2cd..3ce6fab23f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/StoryViewerRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/StoryViewerRepository.kt @@ -4,6 +4,7 @@ import io.reactivex.rxjava3.core.Single import io.reactivex.rxjava3.schedulers.Schedulers import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.database.model.DistributionListId +import org.thoughtcrime.securesms.database.model.StoryViewState import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.recipients.RecipientId @@ -11,7 +12,7 @@ import org.thoughtcrime.securesms.recipients.RecipientId * Open for testing */ open class StoryViewerRepository { - fun getStories(hiddenStories: Boolean): Single> { + fun getStories(hiddenStories: Boolean, unviewedOnly: Boolean): Single> { return Single.create> { emitter -> val myStoriesId = SignalDatabase.recipients.getOrInsertFromDistributionListId(DistributionListId.MY_STORY) val myStories = Recipient.resolved(myStoriesId) @@ -28,6 +29,16 @@ open class StoryViewerRepository { } else { !it.shouldHideStory() } + }.filter { + if (unviewedOnly) { + if (it.isSelf || it.isMyStory) { + false + } else { + SignalDatabase.mms.getStoryViewState(it.id) == StoryViewState.UNVIEWED + } + } else { + true + } }.map { it.id } emitter.onSuccess( diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/StoryViewerViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/StoryViewerViewModel.kt index bb66ff14c2..1709962342 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/StoryViewerViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/StoryViewerViewModel.kt @@ -70,7 +70,10 @@ class StoryViewerViewModel( return if (storyViewerArgs.recipientIds.isNotEmpty()) { Single.just(storyViewerArgs.recipientIds) } else { - repository.getStories(storyViewerArgs.isInHiddenStoryMode) + repository.getStories( + hiddenStories = storyViewerArgs.isInHiddenStoryMode, + unviewedOnly = storyViewerArgs.isUnviewedOnly + ) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/page/StoryViewerPageFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/page/StoryViewerPageFragment.kt index ee38f9af0b..59f3700875 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/page/StoryViewerPageFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/page/StoryViewerPageFragment.kt @@ -95,7 +95,7 @@ class StoryViewerPageFragment : private val viewModel: StoryViewerPageViewModel by viewModels( factoryProducer = { - StoryViewerPageViewModel.Factory(storyRecipientId, initialStoryId, StoryViewerPageRepository(requireContext())) + StoryViewerPageViewModel.Factory(storyRecipientId, initialStoryId, isUnviewedOnly, StoryViewerPageRepository(requireContext())) } ) @@ -120,6 +120,9 @@ class StoryViewerPageFragment : private val groupReplyStartPosition: Int get() = requireArguments().getInt(ARG_GROUP_REPLY_START_POSITION, -1) + private val isUnviewedOnly: Boolean + get() = requireArguments().getBoolean(ARG_IS_UNVIEWED_ONLY, false) + @SuppressLint("ClickableViewAccessibility") override fun onViewCreated(view: View, savedInstanceState: Bundle?) { callback = requireListener() @@ -832,14 +835,16 @@ class StoryViewerPageFragment : private const val ARG_STORY_ID = "arg.story.id" private const val ARG_IS_FROM_NOTIFICATION = "is_from_notification" private const val ARG_GROUP_REPLY_START_POSITION = "group_reply_start_position" + private const val ARG_IS_UNVIEWED_ONLY = "is_unviewed_only" - fun create(recipientId: RecipientId, initialStoryId: Long, isFromNotification: Boolean, groupReplyStartPosition: Int): Fragment { + fun create(recipientId: RecipientId, initialStoryId: Long, isFromNotification: Boolean, groupReplyStartPosition: Int, isUnviewedOnly: Boolean): Fragment { return StoryViewerPageFragment().apply { arguments = Bundle().apply { putParcelable(ARG_STORY_RECIPIENT_ID, recipientId) putLong(ARG_STORY_ID, initialStoryId) putBoolean(ARG_IS_FROM_NOTIFICATION, isFromNotification) putInt(ARG_GROUP_REPLY_START_POSITION, groupReplyStartPosition) + putBoolean(ARG_IS_UNVIEWED_ONLY, isUnviewedOnly) } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/page/StoryViewerPageRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/page/StoryViewerPageRepository.kt index 1f94e59c15..5196e0c84c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/page/StoryViewerPageRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/page/StoryViewerPageRepository.kt @@ -35,13 +35,15 @@ open class StoryViewerPageRepository(context: Context) { private val context = context.applicationContext - private fun getStoryRecords(recipientId: RecipientId): Observable> { + private fun getStoryRecords(recipientId: RecipientId, isUnviewedOnly: Boolean): Observable> { return Observable.create { emitter -> val recipient = Recipient.resolved(recipientId) fun refresh() { val stories = if (recipient.isMyStory) { SignalDatabase.mms.getAllOutgoingStories(false) + } else if (isUnviewedOnly) { + SignalDatabase.mms.getUnreadStories(recipientId, 100) } else { SignalDatabase.mms.getAllStoriesFor(recipientId) } @@ -144,8 +146,8 @@ open class StoryViewerPageRepository(context: Context) { return Stories.enqueueAttachmentsFromStoryForDownload(post.conversationMessage.messageRecord as MmsMessageRecord, true) } - fun getStoryPostsFor(recipientId: RecipientId): Observable> { - return getStoryRecords(recipientId) + fun getStoryPostsFor(recipientId: RecipientId, isUnviewedOnly: Boolean): Observable> { + return getStoryRecords(recipientId, isUnviewedOnly) .switchMap { records -> val posts = records.map { getStoryPostFromRecord(recipientId, it) } if (posts.isEmpty()) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/page/StoryViewerPageViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/page/StoryViewerPageViewModel.kt index f43665e710..2752de89fd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/page/StoryViewerPageViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/viewer/page/StoryViewerPageViewModel.kt @@ -24,6 +24,7 @@ import kotlin.math.min class StoryViewerPageViewModel( private val recipientId: RecipientId, private val initialStoryId: Long, + private val isUnviewedOnly: Boolean, private val repository: StoryViewerPageRepository ) : ViewModel() { @@ -47,7 +48,7 @@ class StoryViewerPageViewModel( fun refresh() { disposables.clear() - disposables += repository.getStoryPostsFor(recipientId).subscribe { posts -> + disposables += repository.getStoryPostsFor(recipientId, isUnviewedOnly).subscribe { posts -> store.update { state -> var isDisplayingInitialState = false val startIndex = if (state.posts.isEmpty() && initialStoryId > 0) { @@ -237,9 +238,14 @@ class StoryViewerPageViewModel( return store.state.posts.getOrNull(index) } - class Factory(private val recipientId: RecipientId, private val initialStoryId: Long, private val repository: StoryViewerPageRepository) : ViewModelProvider.Factory { + class Factory( + private val recipientId: RecipientId, + private val initialStoryId: Long, + private val isUnviewedOnly: Boolean, + private val repository: StoryViewerPageRepository + ) : ViewModelProvider.Factory { override fun create(modelClass: Class): T { - return modelClass.cast(StoryViewerPageViewModel(recipientId, initialStoryId, repository)) as T + return modelClass.cast(StoryViewerPageViewModel(recipientId, initialStoryId, isUnviewedOnly, repository)) as T } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/rx/RxStore.kt b/app/src/main/java/org/thoughtcrime/securesms/util/rx/RxStore.kt index 04bfd39eb1..132d4f581d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/rx/RxStore.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/util/rx/RxStore.kt @@ -19,7 +19,7 @@ class RxStore( private val actionSubject = PublishSubject.create<(T) -> T>().toSerialized() val state: T get() = behaviorProcessor.value!! - val stateFlowable: Flowable = behaviorProcessor + val stateFlowable: Flowable = behaviorProcessor.onBackpressureLatest() init { actionSubject diff --git a/app/src/test/java/org/thoughtcrime/securesms/stories/viewer/StoryViewerViewModelTest.kt b/app/src/test/java/org/thoughtcrime/securesms/stories/viewer/StoryViewerViewModelTest.kt index a2ef1ceea3..775c4b2575 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/stories/viewer/StoryViewerViewModelTest.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/stories/viewer/StoryViewerViewModelTest.kt @@ -35,7 +35,7 @@ class StoryViewerViewModelTest { fun `Given a list of recipients, when I initialize, then I expect the list`() { // GIVEN val repoStories: List = (1L..5L).map(RecipientId::from) - whenever(repository.getStories(any())).doReturn(Single.just(repoStories)) + whenever(repository.getStories(any(), any())).doReturn(Single.just(repoStories)) val injectedStories: List = (6L..10L).map(RecipientId::from) @@ -51,7 +51,7 @@ class StoryViewerViewModelTest { testScheduler.triggerActions() // THEN - verify(repository, never()).getStories(any()) + verify(repository, never()).getStories(any(), any()) assertEquals(injectedStories, testSubject.stateSnapshot.pages) } @@ -60,7 +60,7 @@ class StoryViewerViewModelTest { // GIVEN val stories: List = (1L..5L).map(RecipientId::from) val startStory = RecipientId.from(2L) - whenever(repository.getStories(any())).doReturn(Single.just(stories)) + whenever(repository.getStories(any(), any())).doReturn(Single.just(stories)) // WHEN val testSubject = StoryViewerViewModel( @@ -84,7 +84,7 @@ class StoryViewerViewModelTest { // GIVEN val stories: List = (1L..5L).map(RecipientId::from) val startStory = RecipientId.from(1L) - whenever(repository.getStories(any())).doReturn(Single.just(stories)) + whenever(repository.getStories(any(), any())).doReturn(Single.just(stories)) val testSubject = StoryViewerViewModel( StoryViewerArgs( recipientId = startStory, @@ -110,7 +110,7 @@ class StoryViewerViewModelTest { // GIVEN val stories: List = (1L..5L).map(RecipientId::from) val startStory = stories.last() - whenever(repository.getStories(any())).doReturn(Single.just(stories)) + whenever(repository.getStories(any(), any())).doReturn(Single.just(stories)) val testSubject = StoryViewerViewModel( StoryViewerArgs( recipientId = startStory, @@ -136,7 +136,7 @@ class StoryViewerViewModelTest { // GIVEN val stories: List = (1L..5L).map(RecipientId::from) val startStory = stories.last() - whenever(repository.getStories(any())).doReturn(Single.just(stories)) + whenever(repository.getStories(any(), any())).doReturn(Single.just(stories)) val testSubject = StoryViewerViewModel( StoryViewerArgs( recipientId = startStory, @@ -162,7 +162,7 @@ class StoryViewerViewModelTest { // GIVEN val stories: List = (1L..5L).map(RecipientId::from) val startStory = stories.first() - whenever(repository.getStories(any())).doReturn(Single.just(stories)) + whenever(repository.getStories(any(), any())).doReturn(Single.just(stories)) val testSubject = StoryViewerViewModel( StoryViewerArgs( recipientId = startStory, @@ -188,7 +188,7 @@ class StoryViewerViewModelTest { // GIVEN val stories: List = (1L..5L).map(RecipientId::from) val startStory = stories.first() - whenever(repository.getStories(any())).doReturn(Single.just(stories)) + whenever(repository.getStories(any(), any())).doReturn(Single.just(stories)) val testSubject = StoryViewerViewModel( StoryViewerArgs( recipientId = startStory, diff --git a/app/src/test/java/org/thoughtcrime/securesms/stories/viewer/page/StoryViewerPageViewModelTest.kt b/app/src/test/java/org/thoughtcrime/securesms/stories/viewer/page/StoryViewerPageViewModelTest.kt index 43412d8180..cfeff53b8f 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/stories/viewer/page/StoryViewerPageViewModelTest.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/stories/viewer/page/StoryViewerPageViewModelTest.kt @@ -42,7 +42,7 @@ class StoryViewerPageViewModelTest { fun `Given first page and first post, when I goToPreviousPost, then I expect storyIndex to be 0`() { // GIVEN val storyPosts = createStoryPosts(3) { true } - whenever(repository.getStoryPostsFor(any())).thenReturn(Observable.just(storyPosts)) + whenever(repository.getStoryPostsFor(any(), any())).thenReturn(Observable.just(storyPosts)) val testSubject = createTestSubject() testSubject.setIsFirstPage(true) testScheduler.triggerActions() @@ -61,7 +61,7 @@ class StoryViewerPageViewModelTest { fun `Given first page and second post, when I goToPreviousPost, then I expect storyIndex to be 0`() { // GIVEN val storyPosts = createStoryPosts(3) { true } - whenever(repository.getStoryPostsFor(any())).thenReturn(Observable.just(storyPosts)) + whenever(repository.getStoryPostsFor(any(), any())).thenReturn(Observable.just(storyPosts)) val testSubject = createTestSubject() testSubject.setIsFirstPage(true) testScheduler.triggerActions() @@ -82,7 +82,7 @@ class StoryViewerPageViewModelTest { fun `Given no initial story and 3 records all viewed, when I initialize, then I expect storyIndex to be 0`() { // GIVEN val storyPosts = createStoryPosts(3) { true } - whenever(repository.getStoryPostsFor(any())).thenReturn(Observable.just(storyPosts)) + whenever(repository.getStoryPostsFor(any(), any())).thenReturn(Observable.just(storyPosts)) // WHEN val testSubject = createTestSubject() @@ -98,7 +98,7 @@ class StoryViewerPageViewModelTest { fun `Given no initial story and 3 records all not viewed, when I initialize, then I expect storyIndex to be 0`() { // GIVEN val storyPosts = createStoryPosts(3) { false } - whenever(repository.getStoryPostsFor(any())).thenReturn(Observable.just(storyPosts)) + whenever(repository.getStoryPostsFor(any(), any())).thenReturn(Observable.just(storyPosts)) // WHEN val testSubject = createTestSubject() @@ -114,7 +114,7 @@ class StoryViewerPageViewModelTest { fun `Given no initial story and 3 records with 2nd is not viewed, when I initialize, then I expect storyIndex to be 1`() { // GIVEN val storyPosts = createStoryPosts(3) { it % 2 != 0 } - whenever(repository.getStoryPostsFor(any())).thenReturn(Observable.just(storyPosts)) + whenever(repository.getStoryPostsFor(any(), any())).thenReturn(Observable.just(storyPosts)) // WHEN val testSubject = createTestSubject() @@ -130,7 +130,7 @@ class StoryViewerPageViewModelTest { fun `Given no initial story and 3 records with 1st and 3rd not viewed, when I goToNext, then I expect storyIndex to be 2`() { // GIVEN val storyPosts = createStoryPosts(3) { it % 2 == 0 } - whenever(repository.getStoryPostsFor(any())).thenReturn(Observable.just(storyPosts)) + whenever(repository.getStoryPostsFor(any(), any())).thenReturn(Observable.just(storyPosts)) // WHEN val testSubject = createTestSubject() @@ -148,7 +148,7 @@ class StoryViewerPageViewModelTest { fun `Given a single story, when I goToPrevious, then I expect storyIndex to be -1`() { // GIVEN val storyPosts = createStoryPosts(1) - whenever(repository.getStoryPostsFor(any())).thenReturn(Observable.just(storyPosts)) + whenever(repository.getStoryPostsFor(any(), any())).thenReturn(Observable.just(storyPosts)) // WHEN val testSubject = createTestSubject() @@ -166,6 +166,7 @@ class StoryViewerPageViewModelTest { return StoryViewerPageViewModel( RecipientId.from(1), -1L, + false, repository ) }