kopia lustrzana https://github.com/ryukoposting/Signal-Android
Update stories jump logic to match spec.
rodzic
e8c10cd550
commit
931b9f8831
|
@ -22,7 +22,8 @@ data class StoryViewerArgs(
|
||||||
val groupReplyStartPosition: Int = -1,
|
val groupReplyStartPosition: Int = -1,
|
||||||
val isFromInfoContextMenuAction: Boolean = false,
|
val isFromInfoContextMenuAction: Boolean = false,
|
||||||
val isFromQuote: Boolean = false,
|
val isFromQuote: Boolean = false,
|
||||||
val isFromMyStories: Boolean = false
|
val isFromMyStories: Boolean = false,
|
||||||
|
val isJumpToUnviewed: Boolean = false
|
||||||
) : Parcelable {
|
) : Parcelable {
|
||||||
|
|
||||||
class Builder(private val recipientId: RecipientId, private val isInHiddenStoryMode: Boolean) {
|
class Builder(private val recipientId: RecipientId, private val isInHiddenStoryMode: Boolean) {
|
||||||
|
|
|
@ -33,6 +33,7 @@ import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectFor
|
||||||
import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFragmentArgs
|
import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFragmentArgs
|
||||||
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
|
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
|
||||||
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
|
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
|
||||||
|
import org.thoughtcrime.securesms.database.model.StoryViewState
|
||||||
import org.thoughtcrime.securesms.main.Material3OnScrollHelperBinder
|
import org.thoughtcrime.securesms.main.Material3OnScrollHelperBinder
|
||||||
import org.thoughtcrime.securesms.main.SearchBinder
|
import org.thoughtcrime.securesms.main.SearchBinder
|
||||||
import org.thoughtcrime.securesms.mediasend.v2.MediaSelectionActivity
|
import org.thoughtcrime.securesms.mediasend.v2.MediaSelectionActivity
|
||||||
|
@ -306,8 +307,9 @@ class StoriesLandingFragment : DSLSettingsFragment(layoutId = R.layout.stories_l
|
||||||
storyThumbTextModel = text,
|
storyThumbTextModel = text,
|
||||||
storyThumbUri = image,
|
storyThumbUri = image,
|
||||||
storyThumbBlur = blur,
|
storyThumbBlur = blur,
|
||||||
recipientIds = viewModel.getRecipientIds(model.data.isHidden, false),
|
recipientIds = viewModel.getRecipientIds(model.data.isHidden, model.data.storyViewState == StoryViewState.UNVIEWED),
|
||||||
isFromInfoContextMenuAction = isFromInfoContextMenuAction
|
isFromInfoContextMenuAction = isFromInfoContextMenuAction,
|
||||||
|
isJumpToUnviewed = model.data.storyViewState == StoryViewState.UNVIEWED
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
options.toBundle()
|
options.toBundle()
|
||||||
|
|
|
@ -7,8 +7,10 @@ import androidx.fragment.app.viewModels
|
||||||
import androidx.viewpager2.widget.ViewPager2
|
import androidx.viewpager2.widget.ViewPager2
|
||||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||||
import org.thoughtcrime.securesms.R
|
import org.thoughtcrime.securesms.R
|
||||||
|
import org.thoughtcrime.securesms.recipients.Recipient
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||||
import org.thoughtcrime.securesms.stories.StoryViewerArgs
|
import org.thoughtcrime.securesms.stories.StoryViewerArgs
|
||||||
|
import org.thoughtcrime.securesms.stories.viewer.page.StoryViewerPageArgs
|
||||||
import org.thoughtcrime.securesms.stories.viewer.page.StoryViewerPageFragment
|
import org.thoughtcrime.securesms.stories.viewer.page.StoryViewerPageFragment
|
||||||
import org.thoughtcrime.securesms.stories.viewer.reply.StoriesSharedElementCrossFaderView
|
import org.thoughtcrime.securesms.stories.viewer.reply.StoriesSharedElementCrossFaderView
|
||||||
import org.thoughtcrime.securesms.util.LifecycleDisposable
|
import org.thoughtcrime.securesms.util.LifecycleDisposable
|
||||||
|
@ -47,11 +49,18 @@ class StoryViewerFragment :
|
||||||
|
|
||||||
val adapter = StoryViewerPagerAdapter(
|
val adapter = StoryViewerPagerAdapter(
|
||||||
this,
|
this,
|
||||||
storyViewerArgs.storyId,
|
StoryViewerPageArgs(
|
||||||
storyViewerArgs.isFromNotification,
|
recipientId = Recipient.UNKNOWN.id,
|
||||||
storyViewerArgs.groupReplyStartPosition,
|
initialStoryId = storyViewerArgs.storyId,
|
||||||
storyViewerArgs.isFromMyStories,
|
isJumpForwardToUnviewed = storyViewerArgs.isJumpToUnviewed,
|
||||||
storyViewerArgs.isFromInfoContextMenuAction
|
isOutgoingOnly = storyViewerArgs.isFromMyStories,
|
||||||
|
source = when {
|
||||||
|
storyViewerArgs.isFromInfoContextMenuAction -> StoryViewerPageArgs.Source.INFO_CONTEXT
|
||||||
|
storyViewerArgs.isFromNotification -> StoryViewerPageArgs.Source.NOTIFICATION
|
||||||
|
else -> StoryViewerPageArgs.Source.UNKNOWN
|
||||||
|
},
|
||||||
|
groupReplyStartPosition = storyViewerArgs.groupReplyStartPosition
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
storyPager.adapter = adapter
|
storyPager.adapter = adapter
|
||||||
|
|
|
@ -5,15 +5,12 @@ import androidx.recyclerview.widget.DiffUtil
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||||
|
import org.thoughtcrime.securesms.stories.viewer.page.StoryViewerPageArgs
|
||||||
import org.thoughtcrime.securesms.stories.viewer.page.StoryViewerPageFragment
|
import org.thoughtcrime.securesms.stories.viewer.page.StoryViewerPageFragment
|
||||||
|
|
||||||
class StoryViewerPagerAdapter(
|
class StoryViewerPagerAdapter(
|
||||||
fragment: Fragment,
|
fragment: Fragment,
|
||||||
private val initialStoryId: Long,
|
private val arguments: StoryViewerPageArgs
|
||||||
private val isFromNotification: Boolean,
|
|
||||||
private val groupReplyStartPosition: Int,
|
|
||||||
private val isOutgoingOnly: Boolean,
|
|
||||||
private val isFromInfoContextMenuAction: Boolean
|
|
||||||
) : FragmentStateAdapter(fragment) {
|
) : FragmentStateAdapter(fragment) {
|
||||||
|
|
||||||
private val pages: MutableList<RecipientId> = mutableListOf()
|
private val pages: MutableList<RecipientId> = mutableListOf()
|
||||||
|
@ -39,7 +36,7 @@ class StoryViewerPagerAdapter(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createFragment(position: Int): Fragment {
|
override fun createFragment(position: Int): Fragment {
|
||||||
return StoryViewerPageFragment.create(pages[position], initialStoryId, isFromNotification, groupReplyStartPosition, isOutgoingOnly, isFromInfoContextMenuAction)
|
return StoryViewerPageFragment.create(arguments.copy(recipientId = pages[position]))
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Callback(
|
private class Callback(
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
package org.thoughtcrime.securesms.stories.viewer.page
|
||||||
|
|
||||||
|
import android.os.Parcelable
|
||||||
|
import kotlinx.parcelize.Parcelize
|
||||||
|
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||||
|
|
||||||
|
@Parcelize
|
||||||
|
data class StoryViewerPageArgs(
|
||||||
|
val recipientId: RecipientId,
|
||||||
|
val initialStoryId: Long,
|
||||||
|
val isOutgoingOnly: Boolean,
|
||||||
|
val isJumpForwardToUnviewed: Boolean,
|
||||||
|
val source: Source,
|
||||||
|
val groupReplyStartPosition: Int
|
||||||
|
) : Parcelable {
|
||||||
|
enum class Source {
|
||||||
|
UNKNOWN,
|
||||||
|
NOTIFICATION,
|
||||||
|
INFO_CONTEXT
|
||||||
|
}
|
||||||
|
}
|
|
@ -124,9 +124,7 @@ class StoryViewerPageFragment :
|
||||||
private val viewModel: StoryViewerPageViewModel by viewModels(
|
private val viewModel: StoryViewerPageViewModel by viewModels(
|
||||||
factoryProducer = {
|
factoryProducer = {
|
||||||
StoryViewerPageViewModel.Factory(
|
StoryViewerPageViewModel.Factory(
|
||||||
storyRecipientId,
|
storyViewerPageArgs,
|
||||||
initialStoryId,
|
|
||||||
isOutgoingOnly,
|
|
||||||
StoryViewerPageRepository(
|
StoryViewerPageRepository(
|
||||||
requireContext()
|
requireContext()
|
||||||
),
|
),
|
||||||
|
@ -149,23 +147,7 @@ class StoryViewerPageFragment :
|
||||||
|
|
||||||
private var sendingProgressDrawable: IndeterminateDrawable<CircularProgressIndicatorSpec>? = null
|
private var sendingProgressDrawable: IndeterminateDrawable<CircularProgressIndicatorSpec>? = null
|
||||||
|
|
||||||
private val storyRecipientId: RecipientId
|
private val storyViewerPageArgs: StoryViewerPageArgs by lazy(LazyThreadSafetyMode.NONE) { requireArguments().getParcelable(ARGS)!! }
|
||||||
get() = requireArguments().getParcelable(ARG_STORY_RECIPIENT_ID)!!
|
|
||||||
|
|
||||||
private val initialStoryId: Long
|
|
||||||
get() = requireArguments().getLong(ARG_STORY_ID, -1L)
|
|
||||||
|
|
||||||
private val isFromNotification: Boolean
|
|
||||||
get() = requireArguments().getBoolean(ARG_IS_FROM_NOTIFICATION, false)
|
|
||||||
|
|
||||||
private val groupReplyStartPosition: Int
|
|
||||||
get() = requireArguments().getInt(ARG_GROUP_REPLY_START_POSITION, -1)
|
|
||||||
|
|
||||||
private val isOutgoingOnly: Boolean
|
|
||||||
get() = requireArguments().getBoolean(ARG_IS_OUTGOING_ONLY, false)
|
|
||||||
|
|
||||||
private val isFromInfoContextMenuAction: Boolean
|
|
||||||
get() = requireArguments().getBoolean(ARG_IS_FROM_INFO_CONTEXT_MENU_ACTION, false)
|
|
||||||
|
|
||||||
@SuppressLint("ClickableViewAccessibility")
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
@ -357,7 +339,7 @@ class StoryViewerPageFragment :
|
||||||
|
|
||||||
if (parentState.pages.size <= parentState.page) {
|
if (parentState.pages.size <= parentState.page) {
|
||||||
viewModel.setIsSelectedPage(false)
|
viewModel.setIsSelectedPage(false)
|
||||||
} else if (storyRecipientId == parentState.pages[parentState.page]) {
|
} else if (storyViewerPageArgs.recipientId == parentState.pages[parentState.page]) {
|
||||||
if (progressBar.segmentCount != 0) {
|
if (progressBar.segmentCount != 0) {
|
||||||
progressBar.reset()
|
progressBar.reset()
|
||||||
progressBar.setPosition(viewModel.getRestartIndex())
|
progressBar.setPosition(viewModel.getRestartIndex())
|
||||||
|
@ -412,16 +394,16 @@ class StoryViewerPageFragment :
|
||||||
|
|
||||||
viewModel.setAreSegmentsInitialized(true)
|
viewModel.setAreSegmentsInitialized(true)
|
||||||
} else if (state.selectedPostIndex >= state.posts.size) {
|
} else if (state.selectedPostIndex >= state.posts.size) {
|
||||||
callback.onFinishedPosts(storyRecipientId)
|
callback.onFinishedPosts(storyViewerPageArgs.recipientId)
|
||||||
} else if (state.selectedPostIndex < 0) {
|
} else if (state.selectedPostIndex < 0) {
|
||||||
callback.onGoToPreviousStory(storyRecipientId)
|
callback.onGoToPreviousStory(storyViewerPageArgs.recipientId)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.isDisplayingInitialState && !sharedViewModel.hasConsumedInitialState) {
|
if (state.isDisplayingInitialState && !sharedViewModel.hasConsumedInitialState) {
|
||||||
sharedViewModel.consumeInitialState()
|
sharedViewModel.consumeInitialState()
|
||||||
if (isFromNotification) {
|
if (storyViewerPageArgs.source == StoryViewerPageArgs.Source.NOTIFICATION) {
|
||||||
startReply(isFromNotification = true, groupReplyStartPosition = groupReplyStartPosition)
|
startReply(isFromNotification = true, groupReplyStartPosition = storyViewerPageArgs.groupReplyStartPosition)
|
||||||
} else if (isFromInfoContextMenuAction && state.selectedPostIndex in state.posts.indices) {
|
} else if (storyViewerPageArgs.source == StoryViewerPageArgs.Source.INFO_CONTEXT && state.selectedPostIndex in state.posts.indices) {
|
||||||
showInfo(state.posts[state.selectedPostIndex])
|
showInfo(state.posts[state.selectedPostIndex])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1060,13 +1042,13 @@ class StoryViewerPageFragment :
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onGoToChat = {
|
onGoToChat = {
|
||||||
startActivity(ConversationIntents.createBuilder(requireContext(), storyRecipientId, -1L).build())
|
startActivity(ConversationIntents.createBuilder(requireContext(), storyViewerPageArgs.recipientId, -1L).build())
|
||||||
},
|
},
|
||||||
onHide = {
|
onHide = {
|
||||||
viewModel.setIsDisplayingHideDialog(true)
|
viewModel.setIsDisplayingHideDialog(true)
|
||||||
StoryDialogs.hideStory(requireContext(), Recipient.resolved(storyRecipientId).getDisplayName(requireContext()), { viewModel.setIsDisplayingHideDialog(true) }) {
|
StoryDialogs.hideStory(requireContext(), Recipient.resolved(storyViewerPageArgs.recipientId).getDisplayName(requireContext()), { viewModel.setIsDisplayingHideDialog(true) }) {
|
||||||
lifecycleDisposable += viewModel.hideStory().subscribe {
|
lifecycleDisposable += viewModel.hideStory().subscribe {
|
||||||
callback.onStoryHidden(storyRecipientId)
|
callback.onStoryHidden(storyViewerPageArgs.recipientId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1099,29 +1081,12 @@ class StoryViewerPageFragment :
|
||||||
private val CHARACTERS_PER_SECOND = 15L
|
private val CHARACTERS_PER_SECOND = 15L
|
||||||
private val DEFAULT_DURATION = TimeUnit.SECONDS.toMillis(5)
|
private val DEFAULT_DURATION = TimeUnit.SECONDS.toMillis(5)
|
||||||
|
|
||||||
private const val ARG_STORY_RECIPIENT_ID = "arg.story.recipient.id"
|
private const val ARGS = "args"
|
||||||
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_OUTGOING_ONLY = "is_outgoing_only"
|
|
||||||
private const val ARG_IS_FROM_INFO_CONTEXT_MENU_ACTION = "is_from_info_context_menu_action"
|
|
||||||
|
|
||||||
fun create(
|
fun create(args: StoryViewerPageArgs): Fragment {
|
||||||
recipientId: RecipientId,
|
|
||||||
initialStoryId: Long,
|
|
||||||
isFromNotification: Boolean,
|
|
||||||
groupReplyStartPosition: Int,
|
|
||||||
isOutgoingOnly: Boolean,
|
|
||||||
isFromInfoContextMenuAction: Boolean
|
|
||||||
): Fragment {
|
|
||||||
return StoryViewerPageFragment().apply {
|
return StoryViewerPageFragment().apply {
|
||||||
arguments = bundleOf(
|
arguments = bundleOf(
|
||||||
ARG_STORY_RECIPIENT_ID to recipientId,
|
ARGS to args
|
||||||
ARG_STORY_ID to initialStoryId,
|
|
||||||
ARG_IS_FROM_NOTIFICATION to isFromNotification,
|
|
||||||
ARG_GROUP_REPLY_START_POSITION to groupReplyStartPosition,
|
|
||||||
ARG_IS_OUTGOING_ONLY to isOutgoingOnly,
|
|
||||||
ARG_IS_FROM_INFO_CONTEXT_MENU_ACTION to isFromInfoContextMenuAction,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,9 +25,7 @@ import kotlin.math.min
|
||||||
* Encapsulates presentation logic for displaying a collection of posts from a given user's story
|
* Encapsulates presentation logic for displaying a collection of posts from a given user's story
|
||||||
*/
|
*/
|
||||||
class StoryViewerPageViewModel(
|
class StoryViewerPageViewModel(
|
||||||
private val recipientId: RecipientId,
|
private val args: StoryViewerPageArgs,
|
||||||
private val initialStoryId: Long,
|
|
||||||
private val isOutgoingOnly: Boolean,
|
|
||||||
private val repository: StoryViewerPageRepository,
|
private val repository: StoryViewerPageRepository,
|
||||||
val storyCache: StoryCache
|
val storyCache: StoryCache
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
|
@ -63,11 +61,11 @@ class StoryViewerPageViewModel(
|
||||||
|
|
||||||
fun refresh() {
|
fun refresh() {
|
||||||
disposables.clear()
|
disposables.clear()
|
||||||
disposables += repository.getStoryPostsFor(recipientId, isOutgoingOnly).subscribe { posts ->
|
disposables += repository.getStoryPostsFor(args.recipientId, args.isOutgoingOnly).subscribe { posts ->
|
||||||
store.update { state ->
|
store.update { state ->
|
||||||
val isDisplayingInitialState = state.posts.isEmpty() && posts.isNotEmpty()
|
val isDisplayingInitialState = state.posts.isEmpty() && posts.isNotEmpty()
|
||||||
val startIndex = if (state.posts.isEmpty() && initialStoryId > 0) {
|
val startIndex = if (state.posts.isEmpty() && args.initialStoryId > 0) {
|
||||||
val initialIndex = posts.indexOfFirst { it.id == initialStoryId }
|
val initialIndex = posts.indexOfFirst { it.id == args.initialStoryId }
|
||||||
initialIndex.takeIf { it > -1 } ?: state.selectedPostIndex
|
initialIndex.takeIf { it > -1 } ?: state.selectedPostIndex
|
||||||
} else if (state.posts.isEmpty()) {
|
} else if (state.posts.isEmpty()) {
|
||||||
val initialPost = getNextUnreadPost(posts)
|
val initialPost = getNextUnreadPost(posts)
|
||||||
|
@ -104,7 +102,7 @@ class StoryViewerPageViewModel(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun hideStory(): Completable {
|
fun hideStory(): Completable {
|
||||||
return repository.hideStory(recipientId)
|
return repository.hideStory(args.recipientId)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun markViewed(storyPost: StoryPost) {
|
fun markViewed(storyPost: StoryPost) {
|
||||||
|
@ -133,10 +131,10 @@ class StoryViewerPageViewModel(
|
||||||
|
|
||||||
val postIndex = store.state.selectedPostIndex
|
val postIndex = store.state.selectedPostIndex
|
||||||
val nextUnreadPost: StoryPost? = getNextUnreadPost(store.state.posts.drop(postIndex + 1))
|
val nextUnreadPost: StoryPost? = getNextUnreadPost(store.state.posts.drop(postIndex + 1))
|
||||||
if (nextUnreadPost == null) {
|
when {
|
||||||
setSelectedPostIndex(postIndex + 1)
|
nextUnreadPost == null && args.isJumpForwardToUnviewed -> setSelectedPostIndex(store.state.posts.size)
|
||||||
} else {
|
nextUnreadPost == null -> setSelectedPostIndex(postIndex + 1)
|
||||||
setSelectedPostIndex(store.state.posts.indexOf(nextUnreadPost))
|
else -> setSelectedPostIndex(store.state.posts.indexOf(nextUnreadPost))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,14 +309,12 @@ class StoryViewerPageViewModel(
|
||||||
}
|
}
|
||||||
|
|
||||||
class Factory(
|
class Factory(
|
||||||
private val recipientId: RecipientId,
|
private val args: StoryViewerPageArgs,
|
||||||
private val initialStoryId: Long,
|
|
||||||
private val isOutgoingOnly: Boolean,
|
|
||||||
private val repository: StoryViewerPageRepository,
|
private val repository: StoryViewerPageRepository,
|
||||||
private val storyCache: StoryCache
|
private val storyCache: StoryCache
|
||||||
) : ViewModelProvider.Factory {
|
) : ViewModelProvider.Factory {
|
||||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||||
return modelClass.cast(StoryViewerPageViewModel(recipientId, initialStoryId, isOutgoingOnly, repository, storyCache)) as T
|
return modelClass.cast(StoryViewerPageViewModel(args, repository, storyCache)) as T
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,6 +145,24 @@ class StoryViewerPageViewModelTest {
|
||||||
testSubscriber.assertValueAt(0) { it.selectedPostIndex == 2 }
|
testSubscriber.assertValueAt(0) { it.selectedPostIndex == 2 }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `Given no unread and jump to next unread enabled, when I goToNext, then I expect storyIndex to be size`() {
|
||||||
|
// GIVEN
|
||||||
|
val storyPosts = createStoryPosts(3) { true }
|
||||||
|
whenever(repository.getStoryPostsFor(any(), any())).thenReturn(Observable.just(storyPosts))
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
val testSubject = createTestSubject(isJumpForwardToUnviewed = true)
|
||||||
|
testScheduler.triggerActions()
|
||||||
|
testSubject.goToNextPost()
|
||||||
|
testScheduler.triggerActions()
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
val testSubscriber = testSubject.state.test()
|
||||||
|
|
||||||
|
testSubscriber.assertValueAt(0) { it.selectedPostIndex == 3 }
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `Given a single story, when I goToPrevious, then I expect storyIndex to be -1`() {
|
fun `Given a single story, when I goToPrevious, then I expect storyIndex to be -1`() {
|
||||||
// GIVEN
|
// GIVEN
|
||||||
|
@ -163,11 +181,16 @@ class StoryViewerPageViewModelTest {
|
||||||
testSubscriber.assertValueAt(0) { it.selectedPostIndex == -1 }
|
testSubscriber.assertValueAt(0) { it.selectedPostIndex == -1 }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createTestSubject(): StoryViewerPageViewModel {
|
private fun createTestSubject(isJumpForwardToUnviewed: Boolean = false): StoryViewerPageViewModel {
|
||||||
return StoryViewerPageViewModel(
|
return StoryViewerPageViewModel(
|
||||||
RecipientId.from(1),
|
StoryViewerPageArgs(
|
||||||
-1L,
|
recipientId = RecipientId.from(1),
|
||||||
false,
|
initialStoryId = -1L,
|
||||||
|
isOutgoingOnly = false,
|
||||||
|
isJumpForwardToUnviewed = isJumpForwardToUnviewed,
|
||||||
|
source = StoryViewerPageArgs.Source.UNKNOWN,
|
||||||
|
groupReplyStartPosition = -1
|
||||||
|
),
|
||||||
repository,
|
repository,
|
||||||
mock()
|
mock()
|
||||||
)
|
)
|
||||||
|
|
Ładowanie…
Reference in New Issue