kopia lustrzana https://github.com/ryukoposting/Signal-Android
Allow media selection recipient selection fragment to display in user's chosen app theme.
rodzic
09b92a6559
commit
b20658c829
|
@ -371,6 +371,11 @@
|
|||
android:launchMode="singleTop"
|
||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
||||
|
||||
<activity android:name=".conversation.mutiselect.forward.MultiselectForwardActivity"
|
||||
android:theme="@style/Signal.DayNight.NoActionBar"
|
||||
android:windowSoftInputMode="stateAlwaysHidden|adjustNothing"
|
||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize" />
|
||||
|
||||
<activity android:name=".PassphraseChangeActivity"
|
||||
android:label="@string/AndroidManifest__change_passphrase"
|
||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
||||
|
|
|
@ -13,10 +13,11 @@ import org.thoughtcrime.securesms.util.DynamicTheme
|
|||
abstract class FragmentWrapperActivity : PassphraseRequiredActivity() {
|
||||
|
||||
protected open val dynamicTheme: DynamicTheme = DynamicNoActionBarTheme()
|
||||
protected open val contentViewId: Int = R.layout.fragment_container
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?, ready: Boolean) {
|
||||
super.onCreate(savedInstanceState, ready)
|
||||
setContentView(R.layout.fragment_container)
|
||||
setContentView(contentViewId)
|
||||
dynamicTheme.onCreate(this)
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
package org.thoughtcrime.securesms.conversation.mutiselect.forward
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.ViewGroup
|
||||
import androidx.activity.result.contract.ActivityResultContract
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.components.FragmentWrapperActivity
|
||||
import org.thoughtcrime.securesms.contacts.paged.ContactSearchKey
|
||||
import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFragment.Companion.RESULT_SELECTION
|
||||
|
||||
class MultiselectForwardActivity : FragmentWrapperActivity(), MultiselectForwardFragment.Callback {
|
||||
|
||||
companion object {
|
||||
private const val ARGS = "args"
|
||||
}
|
||||
|
||||
private val args: MultiselectForwardFragmentArgs get() = intent.getParcelableExtra(ARGS)!!
|
||||
|
||||
override val contentViewId: Int = R.layout.multiselect_forward_activity
|
||||
|
||||
override fun getFragment(): Fragment {
|
||||
return MultiselectForwardFragment.create(args)
|
||||
}
|
||||
|
||||
override fun onFinishForwardAction() = Unit
|
||||
|
||||
override fun exitFlow() {
|
||||
onBackPressedDispatcher.onBackPressed()
|
||||
}
|
||||
|
||||
override fun onSearchInputFocused() = Unit
|
||||
|
||||
override fun setResult(bundle: Bundle) {
|
||||
setResult(RESULT_OK, Intent().putExtras(bundle))
|
||||
}
|
||||
|
||||
@Suppress("WrongViewCast")
|
||||
override fun getContainer(): ViewGroup {
|
||||
return findViewById(R.id.fragment_container_wrapper)
|
||||
}
|
||||
|
||||
override fun getDialogBackgroundColor(): Int {
|
||||
return ContextCompat.getColor(this, R.color.signal_colorBackground)
|
||||
}
|
||||
|
||||
class SelectionContract : ActivityResultContract<MultiselectForwardFragmentArgs, List<ContactSearchKey.RecipientSearchKey>>() {
|
||||
override fun createIntent(context: Context, input: MultiselectForwardFragmentArgs): Intent {
|
||||
return Intent(context, MultiselectForwardActivity::class.java).putExtra(ARGS, input)
|
||||
}
|
||||
|
||||
override fun parseResult(resultCode: Int, intent: Intent?): List<ContactSearchKey.RecipientSearchKey> {
|
||||
return if (resultCode != RESULT_OK) {
|
||||
emptyList()
|
||||
} else if (intent == null || !intent.hasExtra(RESULT_SELECTION)) {
|
||||
throw IllegalStateException("Selection contract requires a selection.")
|
||||
} else {
|
||||
val selection: List<ContactSearchKey.ParcelableRecipientSearchKey> = intent.getParcelableArrayListExtra(RESULT_SELECTION)!!
|
||||
selection.map { it.asRecipientSearchKey() }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,6 +16,7 @@ import android.widget.Toast
|
|||
import androidx.annotation.PluralsRes
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.doOnNextLayout
|
||||
import androidx.core.view.isVisible
|
||||
|
@ -41,7 +42,6 @@ import org.thoughtcrime.securesms.mediasend.v2.stories.ChooseGroupStoryBottomShe
|
|||
import org.thoughtcrime.securesms.mediasend.v2.stories.ChooseStoryTypeBottomSheet
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||
import org.thoughtcrime.securesms.safety.SafetyNumberBottomSheet
|
||||
import org.thoughtcrime.securesms.sharing.MultiShareArgs
|
||||
import org.thoughtcrime.securesms.sharing.ShareSelectionAdapter
|
||||
import org.thoughtcrime.securesms.sharing.ShareSelectionMappingModel
|
||||
import org.thoughtcrime.securesms.stories.Stories
|
||||
|
@ -93,19 +93,12 @@ class MultiselectForwardFragment :
|
|||
private var handler: Handler? = null
|
||||
|
||||
private fun createViewModelFactory(): MultiselectForwardViewModel.Factory {
|
||||
return MultiselectForwardViewModel.Factory(getMultiShareArgs(), isSelectionOnly, MultiselectForwardRepository())
|
||||
return MultiselectForwardViewModel.Factory(args.storySendRequirements, args.multiShareArgs, args.forceSelectionOnly, MultiselectForwardRepository())
|
||||
}
|
||||
|
||||
private fun getMultiShareArgs(): ArrayList<MultiShareArgs> = requireNotNull(requireArguments().getParcelableArrayList(ARG_MULTISHARE_ARGS))
|
||||
|
||||
private val forceDisableAddMessage: Boolean
|
||||
get() = requireArguments().getBoolean(ARG_FORCE_DISABLE_ADD_MESSAGE, false)
|
||||
|
||||
private val isSelectionOnly: Boolean
|
||||
get() = requireArguments().getBoolean(ARG_FORCE_SELECTION_ONLY, false)
|
||||
|
||||
private val sendButtonTint: Int
|
||||
get() = requireArguments().getInt(ARG_SEND_BUTTON_TINT, -1)
|
||||
private val args: MultiselectForwardFragmentArgs by lazy {
|
||||
requireArguments().getParcelable(ARGS)!!
|
||||
}
|
||||
|
||||
override fun onGetLayoutInflater(savedInstanceState: Bundle?): LayoutInflater {
|
||||
return if (parentFragment != null) {
|
||||
|
@ -119,7 +112,7 @@ class MultiselectForwardFragment :
|
|||
view.minimumHeight = resources.displayMetrics.heightPixels
|
||||
|
||||
contactSearchRecycler = view.findViewById(R.id.contact_selection_list)
|
||||
contactSearchMediator = ContactSearchMediator(this, contactSearchRecycler, FeatureFlags.shareSelectionLimit(), !isSingleRecipientSelection(), this::getConfiguration, this::filterContacts)
|
||||
contactSearchMediator = ContactSearchMediator(this, contactSearchRecycler, FeatureFlags.shareSelectionLimit(), !args.selectSingleRecipient, this::getConfiguration, this::filterContacts)
|
||||
|
||||
callback = findListener()!!
|
||||
disposables.bindTo(viewLifecycleOwner.lifecycle)
|
||||
|
@ -147,8 +140,8 @@ class MultiselectForwardFragment :
|
|||
val sendButton: View = bottomBar.findViewById(R.id.share_confirm)
|
||||
val backgroundHelper: View = bottomBar.findViewById(R.id.background_helper)
|
||||
|
||||
if (sendButtonTint != -1) {
|
||||
ViewCompat.setBackgroundTintList(sendButton, ColorStateList.valueOf(sendButtonTint))
|
||||
if (args.sendButtonTint != -1) {
|
||||
ViewCompat.setBackgroundTintList(sendButton, ColorStateList.valueOf(args.sendButtonTint))
|
||||
}
|
||||
|
||||
FullscreenHelper.configureBottomBarLayout(requireActivity(), bottomBarSpacer, bottomBar)
|
||||
|
@ -156,7 +149,7 @@ class MultiselectForwardFragment :
|
|||
backgroundHelper.setBackgroundColor(callback.getDialogBackgroundColor())
|
||||
bottomBarSpacer.setBackgroundColor(callback.getDialogBackgroundColor())
|
||||
|
||||
title?.setText(requireArguments().getInt(ARG_TITLE))
|
||||
title?.setText(args.title)
|
||||
|
||||
addMessage = bottomBar.findViewById(R.id.add_message)
|
||||
|
||||
|
@ -174,7 +167,7 @@ class MultiselectForwardFragment :
|
|||
onSend(it)
|
||||
}
|
||||
|
||||
sendButton.visible = !isSingleRecipientSelection()
|
||||
sendButton.visible = !args.selectSingleRecipient
|
||||
|
||||
shareSelectionRecycler.adapter = shareSelectionAdapter
|
||||
|
||||
|
@ -183,14 +176,14 @@ class MultiselectForwardFragment :
|
|||
container.addView(bottomBarAndSpacer)
|
||||
|
||||
contactSearchMediator.getSelectionState().observe(viewLifecycleOwner) { contactSelection ->
|
||||
if (contactSelection.isNotEmpty() && isSingleRecipientSelection()) {
|
||||
if (contactSelection.isNotEmpty() && args.selectSingleRecipient) {
|
||||
onSend(sendButton)
|
||||
return@observe
|
||||
}
|
||||
|
||||
shareSelectionAdapter.submitList(contactSelection.mapIndexed { index, key -> ShareSelectionMappingModel(key.requireShareContact(), index == 0) })
|
||||
|
||||
addMessage.visible = !forceDisableAddMessage && contactSelection.any { key -> key !is ContactSearchKey.RecipientSearchKey.Story } && getMultiShareArgs().isNotEmpty()
|
||||
addMessage.visible = !args.forceDisableAddMessage && contactSelection.any { key -> key !is ContactSearchKey.RecipientSearchKey.Story } && args.multiShareArgs.isNotEmpty()
|
||||
|
||||
if (contactSelection.isNotEmpty() && !bottomBar.isVisible) {
|
||||
bottomBar.animation = AnimationUtils.loadAnimation(requireContext(), R.anim.slide_fade_from_bottom)
|
||||
|
@ -240,7 +233,7 @@ class MultiselectForwardFragment :
|
|||
super.onResume()
|
||||
|
||||
val now = System.currentTimeMillis()
|
||||
val expiringMessages = getMultiShareArgs().filter { it.expiresAt > 0L }
|
||||
val expiringMessages = args.multiShareArgs.filter { it.expiresAt > 0L }
|
||||
val firstToExpire = expiringMessages.minByOrNull { it.expiresAt }
|
||||
val earliestExpiration = firstToExpire?.expiresAt ?: -1L
|
||||
|
||||
|
@ -314,12 +307,12 @@ class MultiselectForwardFragment :
|
|||
callback.exitFlow()
|
||||
}
|
||||
|
||||
private fun getMessageCount(): Int = getMultiShareArgs().size + if (addMessage.text.isNotEmpty()) 1 else 0
|
||||
private fun getMessageCount(): Int = args.multiShareArgs.size + if (addMessage.text.isNotEmpty()) 1 else 0
|
||||
|
||||
private fun handleMessageExpired() {
|
||||
callback.onFinishForwardAction()
|
||||
dismissibleDialog?.dismiss()
|
||||
Toast.makeText(requireContext(), resources.getQuantityString(R.plurals.MultiselectForwardFragment__couldnt_forward_messages, getMultiShareArgs().size), Toast.LENGTH_LONG).show()
|
||||
Toast.makeText(requireContext(), resources.getQuantityString(R.plurals.MultiselectForwardFragment__couldnt_forward_messages, args.multiShareArgs.size), Toast.LENGTH_LONG).show()
|
||||
callback.exitFlow()
|
||||
}
|
||||
|
||||
|
@ -435,19 +428,15 @@ class MultiselectForwardFragment :
|
|||
}
|
||||
|
||||
private fun includeSms(): Boolean {
|
||||
return Util.isDefaultSmsProvider(requireContext()) && requireArguments().getBoolean(ARG_CAN_SEND_TO_NON_PUSH)
|
||||
}
|
||||
|
||||
private fun isSingleRecipientSelection(): Boolean {
|
||||
return requireArguments().getBoolean(ARG_SELECT_SINGLE_RECIPIENT, false)
|
||||
return Util.isDefaultSmsProvider(requireContext()) && args.canSendToNonPush
|
||||
}
|
||||
|
||||
private fun isSelectedMediaValidForStories(): Boolean {
|
||||
return getMultiShareArgs().all { it.isValidForStories }
|
||||
return args.multiShareArgs.all { it.isValidForStories }
|
||||
}
|
||||
|
||||
private fun isSelectedMediaValidForNonStories(): Boolean {
|
||||
return getMultiShareArgs().all { it.isValidForNonStories }
|
||||
return args.multiShareArgs.all { it.isValidForNonStories }
|
||||
}
|
||||
|
||||
override fun onGroupStoryClicked() {
|
||||
|
@ -478,13 +467,8 @@ class MultiselectForwardFragment :
|
|||
}
|
||||
|
||||
companion object {
|
||||
const val ARG_MULTISHARE_ARGS = "multiselect.forward.fragment.arg.multishare.args"
|
||||
const val ARG_CAN_SEND_TO_NON_PUSH = "multiselect.forward.fragment.arg.can.send.to.non.push"
|
||||
const val ARG_TITLE = "multiselect.forward.fragment.title"
|
||||
const val ARG_FORCE_DISABLE_ADD_MESSAGE = "multiselect.forward.fragment.force.disable.add.message"
|
||||
const val ARG_FORCE_SELECTION_ONLY = "multiselect.forward.fragment.force.disable.add.message"
|
||||
const val ARG_SELECT_SINGLE_RECIPIENT = "multiselect.forward.framgent.select.single.recipient"
|
||||
const val ARG_SEND_BUTTON_TINT = "multiselect.forward.fragment.send.button.tint"
|
||||
const val DIALOG_TITLE = "title"
|
||||
const val ARGS = "args"
|
||||
const val RESULT_KEY = "result_key"
|
||||
const val RESULT_SELECTION = "result_selection_recipients"
|
||||
const val RESULT_SENT = "result_sent"
|
||||
|
@ -506,26 +490,14 @@ class MultiselectForwardFragment :
|
|||
@JvmStatic
|
||||
fun create(multiselectForwardFragmentArgs: MultiselectForwardFragmentArgs): Fragment {
|
||||
return MultiselectForwardFragment().apply {
|
||||
arguments = createArgumentsBundle(multiselectForwardFragmentArgs)
|
||||
arguments = bundleOf(ARGS to multiselectForwardFragmentArgs)
|
||||
}
|
||||
}
|
||||
|
||||
private fun showDialogFragment(supportFragmentManager: FragmentManager, fragment: DialogFragment, multiselectForwardFragmentArgs: MultiselectForwardFragmentArgs) {
|
||||
fragment.arguments = createArgumentsBundle(multiselectForwardFragmentArgs)
|
||||
fragment.arguments = bundleOf(ARGS to multiselectForwardFragmentArgs, DIALOG_TITLE to multiselectForwardFragmentArgs.title)
|
||||
|
||||
fragment.show(supportFragmentManager, BottomSheetUtil.STANDARD_BOTTOM_SHEET_FRAGMENT_TAG)
|
||||
}
|
||||
|
||||
private fun createArgumentsBundle(multiselectForwardFragmentArgs: MultiselectForwardFragmentArgs): Bundle {
|
||||
return Bundle().apply {
|
||||
putParcelableArrayList(ARG_MULTISHARE_ARGS, ArrayList(multiselectForwardFragmentArgs.multiShareArgs))
|
||||
putBoolean(ARG_CAN_SEND_TO_NON_PUSH, multiselectForwardFragmentArgs.canSendToNonPush)
|
||||
putInt(ARG_TITLE, multiselectForwardFragmentArgs.title)
|
||||
putBoolean(ARG_FORCE_DISABLE_ADD_MESSAGE, multiselectForwardFragmentArgs.forceDisableAddMessage)
|
||||
putBoolean(ARG_FORCE_SELECTION_ONLY, multiselectForwardFragmentArgs.forceSelectionOnly)
|
||||
putBoolean(ARG_SELECT_SINGLE_RECIPIENT, multiselectForwardFragmentArgs.selectSingleRecipient)
|
||||
putInt(ARG_SEND_BUTTON_TINT, multiselectForwardFragmentArgs.sendButtonTint)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,9 +2,11 @@ package org.thoughtcrime.securesms.conversation.mutiselect.forward
|
|||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import android.os.Parcelable
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.annotation.WorkerThread
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import org.signal.core.util.StreamUtil
|
||||
import org.signal.core.util.ThreadUtil
|
||||
import org.signal.core.util.concurrent.SignalExecutors
|
||||
|
@ -17,6 +19,7 @@ import org.thoughtcrime.securesms.database.model.MmsMessageRecord
|
|||
import org.thoughtcrime.securesms.mediasend.Media
|
||||
import org.thoughtcrime.securesms.mms.PartAuthority
|
||||
import org.thoughtcrime.securesms.sharing.MultiShareArgs
|
||||
import org.thoughtcrime.securesms.stories.Stories
|
||||
import org.thoughtcrime.securesms.util.MediaUtil
|
||||
import java.util.Optional
|
||||
import java.util.function.Consumer
|
||||
|
@ -31,6 +34,7 @@ import java.util.function.Consumer
|
|||
* @param forceSelectionOnly Force the fragment to only select recipients, never actually performing the send.
|
||||
* @param selectSingleRecipient Only allow the selection of a single recipient.
|
||||
*/
|
||||
@Parcelize
|
||||
data class MultiselectForwardFragmentArgs @JvmOverloads constructor(
|
||||
val canSendToNonPush: Boolean,
|
||||
val multiShareArgs: List<MultiShareArgs> = listOf(),
|
||||
|
@ -38,8 +42,9 @@ data class MultiselectForwardFragmentArgs @JvmOverloads constructor(
|
|||
val forceDisableAddMessage: Boolean = false,
|
||||
val forceSelectionOnly: Boolean = false,
|
||||
val selectSingleRecipient: Boolean = false,
|
||||
@ColorInt val sendButtonTint: Int = -1
|
||||
) {
|
||||
@ColorInt val sendButtonTint: Int = -1,
|
||||
val storySendRequirements: Stories.MediaTransform.SendRequirements = Stories.MediaTransform.SendRequirements.CAN_NOT_SEND
|
||||
) : Parcelable {
|
||||
|
||||
fun withSendButtonTint(@ColorInt sendButtonTint: Int) = copy(sendButtonTint = sendButtonTint)
|
||||
|
||||
|
@ -58,7 +63,8 @@ data class MultiselectForwardFragmentArgs @JvmOverloads constructor(
|
|||
consumer.accept(
|
||||
MultiselectForwardFragmentArgs(
|
||||
isMmsSupported,
|
||||
listOf(multiShareArgs)
|
||||
listOf(multiShareArgs),
|
||||
storySendRequirements = Stories.MediaTransform.SendRequirements.CAN_NOT_SEND
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -79,7 +85,15 @@ data class MultiselectForwardFragmentArgs @JvmOverloads constructor(
|
|||
val canSendToNonPush: Boolean = selectedParts.all { Multiselect.canSendToNonPush(context, it) }
|
||||
val multiShareArgs: List<MultiShareArgs> = conversationMessages.map { buildMultiShareArgs(context, it, selectedParts) }
|
||||
|
||||
ThreadUtil.runOnMain { consumer.accept(MultiselectForwardFragmentArgs(canSendToNonPush, multiShareArgs)) }
|
||||
ThreadUtil.runOnMain {
|
||||
consumer.accept(
|
||||
MultiselectForwardFragmentArgs(
|
||||
canSendToNonPush,
|
||||
multiShareArgs,
|
||||
storySendRequirements = Stories.MediaTransform.SendRequirements.CAN_NOT_SEND
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,11 +7,12 @@ import androidx.core.content.ContextCompat
|
|||
import androidx.fragment.app.setFragmentResult
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.components.FullScreenDialogFragment
|
||||
import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFragment.Companion.DIALOG_TITLE
|
||||
import org.thoughtcrime.securesms.stories.Stories
|
||||
import org.thoughtcrime.securesms.util.fragments.findListener
|
||||
|
||||
class MultiselectForwardFullScreenDialogFragment : FullScreenDialogFragment(), MultiselectForwardFragment.Callback {
|
||||
override fun getTitle(): Int = requireArguments().getInt(MultiselectForwardFragment.ARG_TITLE)
|
||||
override fun getTitle(): Int = requireArguments().getParcelable<MultiselectForwardFragmentArgs>(DIALOG_TITLE)!!.title
|
||||
|
||||
override fun getDialogLayoutResource(): Int = R.layout.fragment_container
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import org.thoughtcrime.securesms.recipients.RecipientId
|
|||
import org.thoughtcrime.securesms.sharing.MultiShareArgs
|
||||
import org.thoughtcrime.securesms.sharing.MultiShareSender
|
||||
import org.thoughtcrime.securesms.stories.Stories
|
||||
import org.whispersystems.signalservice.api.util.Preconditions
|
||||
import java.util.Optional
|
||||
|
||||
class MultiselectForwardRepository {
|
||||
|
@ -21,7 +22,9 @@ class MultiselectForwardRepository {
|
|||
)
|
||||
|
||||
fun checkAllSelectedMediaCanBeSentToStories(records: List<MultiShareArgs>): Single<Stories.MediaTransform.SendRequirements> {
|
||||
if (!Stories.isFeatureEnabled() || records.isEmpty()) {
|
||||
Preconditions.checkArgument(records.isNotEmpty())
|
||||
|
||||
if (!Stories.isFeatureEnabled()) {
|
||||
return Single.just(Stories.MediaTransform.SendRequirements.CAN_NOT_SEND)
|
||||
}
|
||||
|
||||
|
|
|
@ -9,15 +9,21 @@ import org.thoughtcrime.securesms.contacts.paged.ContactSearchKey
|
|||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.mediasend.v2.UntrustedRecords
|
||||
import org.thoughtcrime.securesms.sharing.MultiShareArgs
|
||||
import org.thoughtcrime.securesms.stories.Stories
|
||||
import org.thoughtcrime.securesms.util.livedata.Store
|
||||
|
||||
class MultiselectForwardViewModel(
|
||||
private val storySendRequirements: Stories.MediaTransform.SendRequirements,
|
||||
private val records: List<MultiShareArgs>,
|
||||
private val isSelectionOnly: Boolean,
|
||||
private val repository: MultiselectForwardRepository
|
||||
) : ViewModel() {
|
||||
|
||||
private val store = Store(MultiselectForwardState())
|
||||
private val store = Store(
|
||||
MultiselectForwardState(
|
||||
storySendRequirements = storySendRequirements
|
||||
)
|
||||
)
|
||||
|
||||
val state: LiveData<MultiselectForwardState> = store.stateLiveData
|
||||
val snapshot: MultiselectForwardState get() = store.state
|
||||
|
@ -25,8 +31,10 @@ class MultiselectForwardViewModel(
|
|||
private val disposables = CompositeDisposable()
|
||||
|
||||
init {
|
||||
disposables += repository.checkAllSelectedMediaCanBeSentToStories(records).subscribe { sendRequirements ->
|
||||
store.update { it.copy(storySendRequirements = sendRequirements) }
|
||||
if (records.isNotEmpty()) {
|
||||
disposables += repository.checkAllSelectedMediaCanBeSentToStories(records).subscribe { sendRequirements ->
|
||||
store.update { it.copy(storySendRequirements = sendRequirements) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,12 +96,13 @@ class MultiselectForwardViewModel(
|
|||
}
|
||||
|
||||
class Factory(
|
||||
private val storySendRequirements: Stories.MediaTransform.SendRequirements,
|
||||
private val records: List<MultiShareArgs>,
|
||||
private val isSelectionOnly: Boolean,
|
||||
private val repository: MultiselectForwardRepository,
|
||||
) : ViewModelProvider.Factory {
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
return requireNotNull(modelClass.cast(MultiselectForwardViewModel(records, isSelectionOnly, repository)))
|
||||
return requireNotNull(modelClass.cast(MultiselectForwardViewModel(storySendRequirements, records, isSelectionOnly, repository)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@ import org.thoughtcrime.securesms.contacts.paged.ContactSearchConfiguration
|
|||
import org.thoughtcrime.securesms.contacts.paged.ContactSearchKey
|
||||
import org.thoughtcrime.securesms.contacts.paged.ContactSearchState
|
||||
import org.thoughtcrime.securesms.conversation.MessageSendType
|
||||
import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFullScreenDialogFragment
|
||||
import org.thoughtcrime.securesms.conversation.mutiselect.forward.SearchConfigurationProvider
|
||||
import org.thoughtcrime.securesms.keyboard.emoji.EmojiKeyboardPageFragment
|
||||
import org.thoughtcrime.securesms.keyboard.emoji.search.EmojiSearchFragment
|
||||
|
@ -52,8 +51,7 @@ class MediaSelectionActivity :
|
|||
EmojiKeyboardPageFragment.Callback,
|
||||
EmojiEventListener,
|
||||
EmojiSearchFragment.Callback,
|
||||
SearchConfigurationProvider,
|
||||
MultiselectForwardFullScreenDialogFragment.Callback {
|
||||
SearchConfigurationProvider {
|
||||
|
||||
private var animateInShadowLayerValueAnimator: ValueAnimator? = null
|
||||
private var animateInTextColorValueAnimator: ValueAnimator? = null
|
||||
|
@ -334,10 +332,6 @@ class MediaSelectionActivity :
|
|||
}
|
||||
}
|
||||
|
||||
override fun getStorySendRequirements(): Stories.MediaTransform.SendRequirements {
|
||||
return viewModel.getStorySendRequirements()
|
||||
}
|
||||
|
||||
private inner class OnBackPressed : OnBackPressedCallback(true) {
|
||||
override fun handleOnBackPressed() {
|
||||
val navController = Navigation.findNavController(this@MediaSelectionActivity, R.id.fragment_container)
|
||||
|
|
|
@ -17,7 +17,6 @@ import androidx.core.content.ContextCompat
|
|||
import androidx.core.graphics.drawable.DrawableCompat
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.setFragmentResultListener
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
|
@ -28,7 +27,7 @@ import io.reactivex.rxjava3.disposables.CompositeDisposable
|
|||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.contacts.paged.ContactSearchKey
|
||||
import org.thoughtcrime.securesms.conversation.MessageSendType
|
||||
import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFragment
|
||||
import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardActivity
|
||||
import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFragmentArgs
|
||||
import org.thoughtcrime.securesms.mediasend.MediaSendActivityResult
|
||||
import org.thoughtcrime.securesms.mediasend.v2.HudCommand
|
||||
|
@ -138,16 +137,20 @@ class MediaReviewFragment : Fragment(R.layout.v2_media_review_fragment) {
|
|||
sharedViewModel.sendCommand(HudCommand.SaveMedia)
|
||||
}
|
||||
|
||||
setFragmentResultListener(MultiselectForwardFragment.RESULT_KEY) { _, bundle ->
|
||||
val parcelizedKeys: List<ContactSearchKey.ParcelableRecipientSearchKey> = bundle.getParcelableArrayList(MultiselectForwardFragment.RESULT_SELECTION)!!
|
||||
val contactSearchKeys = parcelizedKeys.map { it.asRecipientSearchKey() }
|
||||
performSend(contactSearchKeys)
|
||||
val recipientSelectionLauncher = registerForActivityResult(MultiselectForwardActivity.SelectionContract()) { keys ->
|
||||
if (keys.isNotEmpty()) {
|
||||
performSend(keys)
|
||||
}
|
||||
}
|
||||
|
||||
sendButton.setOnClickListener {
|
||||
if (sharedViewModel.isContactSelectionRequired) {
|
||||
val args = MultiselectForwardFragmentArgs(false, title = R.string.MediaReviewFragment__send_to)
|
||||
MultiselectForwardFragment.showFullScreen(parentFragmentManager, args)
|
||||
val args = MultiselectForwardFragmentArgs(
|
||||
false,
|
||||
title = R.string.MediaReviewFragment__send_to,
|
||||
storySendRequirements = sharedViewModel.getStorySendRequirements()
|
||||
)
|
||||
recipientSelectionLauncher.launch(args)
|
||||
} else {
|
||||
performSend()
|
||||
}
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/fragment_container_wrapper"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/fragment_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
</FrameLayout>
|
Ładowanie…
Reference in New Issue