Add entry points for adding to a group story.

This commit is contained in:
Alex Hart
2022-11-29 13:12:56 -04:00
committed by Cody Henthorne
parent 7949996c5c
commit 7b13550086
19 changed files with 372 additions and 17 deletions

View File

@@ -93,8 +93,9 @@ class MediaSelectionActivity :
val initialMedia: List<Media> = intent.getParcelableArrayListExtra(MEDIA) ?: listOf()
val message: CharSequence? = if (shareToTextStory) null else draftText
val isReply: Boolean = intent.getBooleanExtra(IS_REPLY, false)
val isAddToGroupStoryFlow: Boolean = intent.getBooleanExtra(IS_ADD_TO_GROUP_STORY_FLOW, false)
val factory = MediaSelectionViewModel.Factory(destination, sendType, initialMedia, message, isReply, isStory, MediaSelectionRepository(this))
val factory = MediaSelectionViewModel.Factory(destination, sendType, initialMedia, message, isReply, isStory, isAddToGroupStoryFlow, MediaSelectionRepository(this))
viewModel = ViewModelProvider(this, factory)[MediaSelectionViewModel::class.java]
val textStoryToggle: ConstraintLayout = findViewById(R.id.switch_widget)
@@ -221,7 +222,7 @@ class MediaSelectionActivity :
return Stories.isFeatureEnabled() &&
isCameraFirst() &&
!viewModel.hasSelectedMedia() &&
destination == MediaSelectionDestination.ChooseAfterMediaSelection
(destination == MediaSelectionDestination.ChooseAfterMediaSelection || destination is MediaSelectionDestination.SingleStory)
}
override fun onSaveInstanceState(outState: Bundle) {
@@ -348,6 +349,7 @@ class MediaSelectionActivity :
private const val IS_REPLY = "is_reply"
private const val IS_STORY = "is_story"
private const val AS_TEXT_STORY = "as_text_story"
private const val IS_ADD_TO_GROUP_STORY_FLOW = "is_add_to_group_story_flow"
@JvmStatic
fun camera(context: Context): Intent {
@@ -363,6 +365,19 @@ class MediaSelectionActivity :
)
}
fun addToGroupStory(
context: Context,
recipientId: RecipientId
): Intent {
return buildIntent(
context = context,
startAction = R.id.action_directly_to_mediaCaptureFragment,
isStory = true,
isAddToGroupStoryFlow = true,
destination = MediaSelectionDestination.SingleStory(recipientId)
)
}
@JvmStatic
fun camera(
context: Context,
@@ -457,7 +472,8 @@ class MediaSelectionActivity :
message: CharSequence? = null,
isReply: Boolean = false,
isStory: Boolean = false,
asTextStory: Boolean = false
asTextStory: Boolean = false,
isAddToGroupStoryFlow: Boolean = false
): Intent {
return Intent(context, MediaSelectionActivity::class.java).apply {
putExtra(START_ACTION, startAction)
@@ -468,6 +484,7 @@ class MediaSelectionActivity :
putExtra(IS_REPLY, isReply)
putExtra(IS_STORY, isStory)
putExtra(AS_TEXT_STORY, asTextStory)
putExtra(IS_ADD_TO_GROUP_STORY_FLOW, isAddToGroupStoryFlow)
}
}
}

View File

@@ -38,6 +38,16 @@ sealed class MediaSelectionDestination {
}
}
class SingleStory(private val id: RecipientId) : MediaSelectionDestination() {
override fun getRecipientSearchKey(): ContactSearchKey.RecipientSearchKey = ContactSearchKey.RecipientSearchKey.Story(id)
override fun toBundle(): Bundle {
return Bundle().apply {
putParcelable(STORY, id)
}
}
}
class MultipleRecipients(val recipientSearchKeys: List<ContactSearchKey.RecipientSearchKey>) : MediaSelectionDestination() {
companion object {
@@ -72,6 +82,7 @@ sealed class MediaSelectionDestination {
private const val WALLPAPER = "wallpaper"
private const val AVATAR = "avatar"
private const val RECIPIENT = "recipient"
private const val STORY = "story"
private const val RECIPIENT_LIST = "recipient_list"
fun fromBundle(bundle: Bundle): MediaSelectionDestination {
@@ -79,6 +90,7 @@ sealed class MediaSelectionDestination {
bundle.containsKey(WALLPAPER) -> Wallpaper
bundle.containsKey(AVATAR) -> Avatar
bundle.containsKey(RECIPIENT) -> SingleRecipient(requireNotNull(bundle.getParcelable(RECIPIENT)))
bundle.containsKey(STORY) -> SingleStory(requireNotNull(bundle.getParcelable(STORY)))
bundle.containsKey(RECIPIENT_LIST) -> MultipleRecipients.fromParcel(requireNotNull(bundle.getParcelableArrayList(RECIPIENT_LIST)))
else -> ChooseAfterMediaSelection
}

View File

@@ -105,6 +105,8 @@ class MediaSelectionRepository(context: Context) {
val singleRecipient: Recipient? = singleContact?.let { Recipient.resolved(it.recipientId) }
val storyType: StoryType = if (singleRecipient?.isDistributionList == true) {
SignalDatabase.distributionLists.getStoryType(singleRecipient.requireDistributionListId())
} else if (singleRecipient?.isGroup == true && singleContact.isStory) {
StoryType.STORY_WITH_REPLIES
} else {
StoryType.NONE
}

View File

@@ -45,6 +45,7 @@ class MediaSelectionViewModel(
initialMessage: CharSequence?,
val isReply: Boolean,
isStory: Boolean,
val isAddToGroupStoryFlow: Boolean,
private val repository: MediaSelectionRepository,
private val identityChangesSince: Long = System.currentTimeMillis()
) : ViewModel() {
@@ -360,10 +361,10 @@ class MediaSelectionViewModel(
return
}
val filteredPreUploadMedia = if (Stories.isFeatureEnabled()) {
media.filter { Stories.MediaTransform.canPreUploadMedia(it) }
} else {
val filteredPreUploadMedia = if (destination is MediaSelectionDestination.SingleRecipient || !Stories.isFeatureEnabled()) {
media
} else {
media.filter { Stories.MediaTransform.canPreUploadMedia(it) }
}
repository.uploadRepository.startUpload(filteredPreUploadMedia, store.state.recipient)
@@ -482,10 +483,11 @@ class MediaSelectionViewModel(
private val initialMessage: CharSequence?,
private val isReply: Boolean,
private val isStory: Boolean,
private val isAddToGroupStoryFlow: Boolean,
private val repository: MediaSelectionRepository
) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return requireNotNull(modelClass.cast(MediaSelectionViewModel(destination, sendType, initialMedia, initialMessage, isReply, isStory, repository)))
return requireNotNull(modelClass.cast(MediaSelectionViewModel(destination, sendType, initialMedia, initialMessage, isReply, isStory, isAddToGroupStoryFlow, repository)))
}
}
}

View File

@@ -23,6 +23,7 @@ import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2
import app.cash.exhaustive.Exhaustive
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import org.signal.core.util.concurrent.SimpleTask
import org.thoughtcrime.securesms.R
@@ -200,6 +201,12 @@ class MediaReviewFragment : Fragment(R.layout.v2_media_review_fragment) {
} else {
multiselectLauncher.launch(args)
}
} else if (sharedViewModel.isAddToGroupStoryFlow) {
MaterialAlertDialogBuilder(requireContext())
.setMessage(getString(R.string.MediaReviewFragment__add_to_the_group_story, sharedViewModel.state.value!!.recipient!!.getDisplayName(requireContext())))
.setPositiveButton(R.string.MediaReviewFragment__add_to_story) { _, _ -> performSend() }
.setNegativeButton(android.R.string.cancel) { _, _ -> }
.show()
} else {
performSend()
}
@@ -317,7 +324,7 @@ class MediaReviewFragment : Fragment(R.layout.v2_media_review_fragment) {
.setInterpolator(MediaAnimations.interpolator)
.alpha(1f)
sharedViewModel
disposables += sharedViewModel
.send(selection.filterIsInstance(ContactSearchKey.RecipientSearchKey::class.java))
.subscribe(
{ result -> callback.onSentWithResult(result) },

View File

@@ -12,6 +12,7 @@ import androidx.core.view.updateLayoutParams
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.contacts.paged.ContactSearchKey
@@ -157,6 +158,12 @@ class TextStoryPostCreationFragment : Fragment(R.layout.stories_text_post_creati
)
)
}
} else if (sharedViewModel.isAddToGroupStoryFlow) {
MaterialAlertDialogBuilder(requireContext())
.setMessage(getString(R.string.MediaReviewFragment__add_to_the_group_story, sharedViewModel.state.value!!.recipient!!.getDisplayName(requireContext())))
.setPositiveButton(R.string.MediaReviewFragment__add_to_story) { _, _ -> performSend(contacts) }
.setNegativeButton(android.R.string.cancel) { _, _ -> }
.show()
} else {
performSend(contacts)
}