Display dialog to confirm hiding story in story viewer.

fork-5.53.8
Alex Hart 2022-09-16 13:29:39 -03:00 zatwierdzone przez Cody Henthorne
rodzic 115d1fcf63
commit 8141b53c15
10 zmienionych plików z 80 dodań i 32 usunięć

Wyświetl plik

@ -41,4 +41,21 @@ object StoryDialogs {
}
.show()
}
fun hideStory(
context: Context,
recipientName: String,
onCancelled: () -> Unit = {},
onHideStoryConfirmed: () -> Unit,
) {
MaterialAlertDialogBuilder(context, R.style.ThemeOverlay_Signal_MaterialAlertDialog)
.setTitle(R.string.StoriesLandingFragment__hide_story)
.setMessage(context.getString(R.string.StoriesLandingFragment__new_story_updates, recipientName))
.setPositiveButton(R.string.StoriesLandingFragment__hide) { _, _ ->
onHideStoryConfirmed()
}
.setNegativeButton(android.R.string.cancel) { _, _ -> onCancelled() }
.setOnCancelListener { onCancelled() }
.show()
}
}

Wyświetl plik

@ -16,7 +16,6 @@ import androidx.core.app.SharedElementCallback
import androidx.core.view.ViewCompat
import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.google.android.material.snackbar.BaseTransientBottomBar
import com.google.android.material.snackbar.Snackbar
@ -33,7 +32,6 @@ import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectFor
import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFragmentArgs
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
@ -273,8 +271,8 @@ class StoriesLandingFragment : DSLSettingsFragment(layoutId = R.layout.stories_l
storyThumbTextModel = text,
storyThumbUri = image,
storyThumbBlur = blur,
recipientIds = viewModel.getRecipientIds(model.data.isHidden, true),
isUnviewedOnly = model.data.storyViewState == StoryViewState.UNVIEWED,
recipientIds = viewModel.getRecipientIds(model.data.isHidden, false),
isUnviewedOnly = false,
isFromInfoContextMenuAction = isFromInfoContextMenuAction
)
),
@ -288,19 +286,14 @@ class StoriesLandingFragment : DSLSettingsFragment(layoutId = R.layout.stories_l
}
private fun handleHideStory(model: StoriesLandingItem.Model) {
MaterialAlertDialogBuilder(requireContext(), R.style.ThemeOverlay_Signal_MaterialAlertDialog)
.setTitle(R.string.StoriesLandingFragment__hide_story)
.setMessage(getString(R.string.StoriesLandingFragment__new_story_updates, model.data.storyRecipient.getShortDisplayName(requireContext())))
.setPositiveButton(R.string.StoriesLandingFragment__hide) { _, _ ->
viewModel.setHideStory(model.data.storyRecipient, true).subscribe {
Snackbar.make(cameraFab, R.string.StoriesLandingFragment__story_hidden, Snackbar.LENGTH_SHORT)
.setAnchorView(cameraFab)
.setAnimationMode(BaseTransientBottomBar.ANIMATION_MODE_FADE)
.show()
}
StoryDialogs.hideStory(requireContext(), model.data.storyRecipient.getShortDisplayName(requireContext())) {
viewModel.setHideStory(model.data.storyRecipient, true).subscribe {
Snackbar.make(cameraFab, R.string.StoriesLandingFragment__story_hidden, Snackbar.LENGTH_SHORT)
.setAnchorView(cameraFab)
.setAnimationMode(BaseTransientBottomBar.ANIMATION_MODE_FADE)
.show()
}
.setNegativeButton(android.R.string.cancel) { _, _ -> }
.show()
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {

Wyświetl plik

@ -66,6 +66,10 @@ class StoryViewerFragment :
lifecycleDisposable.bindTo(viewLifecycleOwner)
lifecycleDisposable += viewModel.state.observeOn(AndroidSchedulers.mainThread()).subscribe { state ->
if (state.noPosts) {
requireActivity().finish()
}
adapter.setPages(state.pages)
if (state.pages.isNotEmpty() && storyPager.currentItem != state.page) {
pagerOnPageSelectedLock = true
@ -96,6 +100,17 @@ class StoryViewerFragment :
storyCrossfader.alpha = 0f
}
}
if (savedInstanceState != null && savedInstanceState.containsKey(HIDDEN)) {
val ids: List<RecipientId> = savedInstanceState.getParcelableArrayList(HIDDEN)!!
viewModel.addHiddenAndRefresh(ids.toSet())
} else {
viewModel.refresh()
}
}
override fun onSaveInstanceState(outState: Bundle) {
outState.putParcelableArrayList(HIDDEN, ArrayList(viewModel.getHidden()))
}
override fun onResume() {
@ -119,7 +134,7 @@ class StoryViewerFragment :
}
override fun onStoryHidden(recipientId: RecipientId) {
viewModel.onRecipientHidden()
viewModel.addHiddenAndRefresh(setOf(recipientId))
}
override fun onReadyToAnimate() {
@ -150,6 +165,7 @@ class StoryViewerFragment :
companion object {
private const val ARGS = "args"
private const val HIDDEN = "hidden"
fun create(storyViewerArgs: StoryViewerArgs): Fragment {
return StoryViewerFragment().apply {

Wyświetl plik

@ -17,11 +17,12 @@ class StoryViewerPagerAdapter(
private val isFromInfoContextMenuAction: Boolean
) : FragmentStateAdapter(fragment) {
private var pages: List<RecipientId> = emptyList()
private val pages: MutableList<RecipientId> = mutableListOf()
fun setPages(newPages: List<RecipientId>) {
val oldPages = pages
pages = newPages
val oldPages = ArrayList(pages)
pages.clear()
pages.addAll(newPages)
val callback = Callback(oldPages, pages)
DiffUtil.calculateDiff(callback).dispatchUpdatesTo(this)
@ -34,6 +35,10 @@ class StoryViewerPagerAdapter(
override fun getItemCount(): Int = pages.size
override fun getItemId(position: Int): Long {
return pages[position].toLong()
}
override fun createFragment(position: Int): Fragment {
return StoryViewerPageFragment.create(pages[position], initialStoryId, isFromNotification, groupReplyStartPosition, isUnviewedOnly, isOutgoingOnly, isFromInfoContextMenuAction)
}

Wyświetl plik

@ -13,7 +13,8 @@ data class StoryViewerState(
val crossfadeSource: CrossfadeSource,
val crossfadeTarget: CrossfadeTarget? = null,
val loadState: LoadState = LoadState(),
val skipCrossfade: Boolean = false
val skipCrossfade: Boolean = false,
val noPosts: Boolean = false
) {
sealed class CrossfadeSource {
object None : CrossfadeSource()

Wyświetl plik

@ -39,6 +39,8 @@ class StoryViewerViewModel(
val stateSnapshot: StoryViewerState get() = store.state
val state: Flowable<StoryViewerState> = store.stateFlowable
private val hidden = mutableSetOf<RecipientId>()
private val scrollStatePublisher: MutableLiveData<Boolean> = MutableLiveData(false)
val isScrolling: LiveData<Boolean> = scrollStatePublisher
@ -53,10 +55,13 @@ class StoryViewerViewModel(
val isChildScrolling: Observable<Boolean> = childScrollStatePublisher.distinctUntilChanged()
init {
fun addHiddenAndRefresh(hidden: Set<RecipientId>) {
this.hidden.addAll(hidden)
refresh()
}
fun getHidden(): Set<RecipientId> = hidden
fun setCrossfadeTarget(messageRecord: MmsMessageRecord) {
store.update {
it.copy(crossfadeTarget = StoryViewerState.CrossfadeTarget.Record(messageRecord))
@ -85,7 +90,7 @@ class StoryViewerViewModel(
private fun getStories(): Single<List<RecipientId>> {
return if (storyViewerArgs.recipientIds.isNotEmpty()) {
Single.just(storyViewerArgs.recipientIds)
Single.just(storyViewerArgs.recipientIds - hidden)
} else {
repository.getStories(
hiddenStories = storyViewerArgs.isInHiddenStoryMode,
@ -95,7 +100,7 @@ class StoryViewerViewModel(
}
}
private fun refresh() {
fun refresh() {
disposables.clear()
disposables += repository.getFirstStory(storyViewerArgs.recipientId, storyViewerArgs.isUnviewedOnly, storyViewerArgs.storyId).subscribe { record ->
store.update {
@ -119,7 +124,7 @@ class StoryViewerViewModel(
} else {
it.page
}
updatePages(it.copy(pages = recipientIds), page)
updatePages(it.copy(pages = recipientIds), page).copy(noPosts = recipientIds.isEmpty())
}
}
disposables += state
@ -167,10 +172,6 @@ class StoryViewerViewModel(
}
}
fun onRecipientHidden() {
refresh()
}
private fun updatePages(state: StoryViewerState, page: Int): StoryViewerState {
val newPage = resolvePage(page, state.pages)
val prevPage = if (newPage == state.page) {

Wyświetl plik

@ -59,6 +59,7 @@ import org.thoughtcrime.securesms.stories.StoryFirstTimeNavigationView
import org.thoughtcrime.securesms.stories.StorySlateView
import org.thoughtcrime.securesms.stories.StoryVolumeOverlayView
import org.thoughtcrime.securesms.stories.dialogs.StoryContextMenu
import org.thoughtcrime.securesms.stories.dialogs.StoryDialogs
import org.thoughtcrime.securesms.stories.viewer.StoryViewerViewModel
import org.thoughtcrime.securesms.stories.viewer.StoryVolumeViewModel
import org.thoughtcrime.securesms.stories.viewer.info.StoryInfoBottomSheetDialogFragment
@ -979,8 +980,11 @@ class StoryViewerPageFragment :
startActivity(ConversationIntents.createBuilder(requireContext(), storyRecipientId, -1L).build())
},
onHide = {
lifecycleDisposable += viewModel.hideStory().subscribe {
callback.onStoryHidden(storyRecipientId)
viewModel.setIsDisplayingHideDialog(true)
StoryDialogs.hideStory(requireContext(), Recipient.resolved(storyRecipientId).getDisplayName(requireContext()), { viewModel.setIsDisplayingHideDialog(true) }) {
lifecycleDisposable += viewModel.hideStory().subscribe {
callback.onStoryHidden(storyRecipientId)
}
}
},
onShare = {

Wyświetl plik

@ -222,6 +222,10 @@ class StoryViewerPageViewModel(
storyViewerPlaybackStore.update { it.copy(isDisplayingDeleteDialog = isDisplayingDeleteDialog) }
}
fun setIsDisplayingHideDialog(isDisplayingHideDialog: Boolean) {
storyViewerPlaybackStore.update { it.copy(isDisplayingHideDialog = isDisplayingHideDialog) }
}
fun setIsDisplayingViewsAndRepliesDialog(isDisplayingViewsAndRepliesDialog: Boolean) {
storyViewerPlaybackStore.update { it.copy(isDisplayingViewsAndRepliesDialog = isDisplayingViewsAndRepliesDialog) }
}

Wyświetl plik

@ -5,6 +5,7 @@ data class StoryViewerPlaybackState(
val isUserTouching: Boolean = false,
val isDisplayingForwardDialog: Boolean = false,
val isDisplayingDeleteDialog: Boolean = false,
val isDisplayingHideDialog: Boolean = false,
val isDisplayingContextMenu: Boolean = false,
val isDisplayingViewsAndRepliesDialog: Boolean = false,
val isDisplayingDirectReplyDialog: Boolean = false,
@ -44,5 +45,6 @@ data class StoryViewerPlaybackState(
isRunningSharedElementAnimation ||
isDisplayingFirstTimeNavigation ||
isDisplayingInfoDialog ||
isUserScaling
isUserScaling ||
isDisplayingHideDialog
}

Wyświetl plik

@ -63,6 +63,7 @@ class StoryViewerViewModelTest {
),
repository
)
testSubject.refresh()
testScheduler.triggerActions()
// THEN
@ -107,6 +108,7 @@ class StoryViewerViewModelTest {
),
repository
)
testSubject.refresh()
testScheduler.triggerActions()
// WHEN
@ -133,6 +135,7 @@ class StoryViewerViewModelTest {
),
repository
)
testSubject.refresh()
testScheduler.triggerActions()
// WHEN
@ -159,6 +162,7 @@ class StoryViewerViewModelTest {
),
repository
)
testSubject.refresh()
testScheduler.triggerActions()
// WHEN
@ -185,6 +189,7 @@ class StoryViewerViewModelTest {
),
repository
)
testSubject.refresh()
testScheduler.triggerActions()
// WHEN