mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-24 21:15:48 +00:00
Add several callbacks to v2 convo fragment.
This commit is contained in:
committed by
Cody Henthorne
parent
279ad7945e
commit
9d17bf473c
@@ -7,7 +7,6 @@ import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.EdgeEffect
|
||||
import androidx.annotation.Discouraged
|
||||
import androidx.annotation.LayoutRes
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
@@ -16,7 +15,6 @@ import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.components.FixedRoundedCornerBottomSheetDialogFragment
|
||||
import org.thoughtcrime.securesms.util.WindowUtil
|
||||
|
||||
@Discouraged("The DSL API can be completely replaced by compose. See ComposeFragment or ComposeBottomSheetFragment for an alternative to this API")
|
||||
abstract class DSLSettingsBottomSheetFragment(
|
||||
@LayoutRes private val layoutId: Int = R.layout.dsl_settings_bottom_sheet,
|
||||
val layoutManagerProducer: (Context) -> RecyclerView.LayoutManager = { context -> LinearLayoutManager(context) },
|
||||
|
||||
@@ -46,6 +46,8 @@ import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import android.widget.ViewSwitcher;
|
||||
|
||||
import androidx.activity.result.ActivityResultCallback;
|
||||
import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
@@ -111,6 +113,7 @@ import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectFor
|
||||
import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFragmentArgs;
|
||||
import org.thoughtcrime.securesms.conversation.quotes.MessageQuotesBottomSheet;
|
||||
import org.thoughtcrime.securesms.conversation.ui.error.EnableCallNotificationSettingsDialog;
|
||||
import org.thoughtcrime.securesms.conversation.v2.AddToContactsContract;
|
||||
import org.thoughtcrime.securesms.database.DatabaseObserver;
|
||||
import org.thoughtcrime.securesms.database.MessageTable;
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase;
|
||||
@@ -216,7 +219,6 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
|
||||
private static final String TAG = Log.tag(ConversationFragment.class);
|
||||
|
||||
private static final int SCROLL_ANIMATION_THRESHOLD = 50;
|
||||
private static final int CODE_ADD_EDIT_CONTACT = 77;
|
||||
private static final int MAX_SCROLL_DELAY_COUNT = 5;
|
||||
|
||||
private final ActionModeCallback actionModeCallback = new ActionModeCallback();
|
||||
@@ -271,6 +273,8 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
|
||||
|
||||
private final DatabaseObserver.Observer threadDeletedObserver = this::onThreadDelete;
|
||||
|
||||
private ActivityResultLauncher<Intent> addToContactsLauncher;
|
||||
|
||||
public static void prepare(@NonNull Context context) {
|
||||
FrameLayout parent = new FrameLayout(context);
|
||||
parent.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT));
|
||||
@@ -294,6 +298,8 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle bundle) {
|
||||
addToContactsLauncher = registerForActivityResult(new AddToContactsContract(), result -> {});
|
||||
|
||||
disposables.bindTo(getViewLifecycleOwner());
|
||||
lastSeenDisposable.bindTo(getViewLifecycleOwner());
|
||||
|
||||
@@ -1819,24 +1825,15 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
|
||||
|
||||
@Override
|
||||
public void onAddToContactsClicked(@NonNull Contact contactWithAvatar) {
|
||||
if (getContext() != null) {
|
||||
new AsyncTask<Void, Void, Intent>() {
|
||||
@Override
|
||||
protected Intent doInBackground(Void... voids) {
|
||||
return ContactUtil.buildAddToContactsIntent(getContext(), contactWithAvatar);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Intent intent) {
|
||||
try {
|
||||
startActivityForResult(intent, CODE_ADD_EDIT_CONTACT);
|
||||
} catch (ActivityNotFoundException e) {
|
||||
Log.w(TAG, "Could not locate contacts activity", e);
|
||||
Toast.makeText(requireContext(), R.string.ConversationFragment__contacts_app_not_found, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
}.execute();
|
||||
if (getContext() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
disposables.add(AddToContactsContract.createIntentAndLaunch(
|
||||
ConversationFragment.this,
|
||||
addToContactsLauncher,
|
||||
contactWithAvatar
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -2149,15 +2146,6 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
|
||||
if (requestCode == CODE_ADD_EDIT_CONTACT && getContext() != null) {
|
||||
ApplicationDependencies.getJobManager().add(new DirectoryRefreshJob(false));
|
||||
}
|
||||
}
|
||||
|
||||
private void handleEnterMultiSelect(@NonNull ConversationMessage conversationMessage) {
|
||||
Set<MultiselectPart> multiselectParts = conversationMessage.getMultiselectCollection().toSet();
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ public class ConversationRepository {
|
||||
return new ConversationData(threadId, lastSeen, lastSeenPosition, lastScrolledPosition, jumpToPosition, threadSize, messageRequestData, showUniversalExpireTimerUpdate);
|
||||
}
|
||||
|
||||
void markGiftBadgeRevealed(long messageId) {
|
||||
public void markGiftBadgeRevealed(long messageId) {
|
||||
SignalExecutors.BOUNDED_IO.execute(() -> {
|
||||
List<MessageTable.MarkedMessageInfo> markedMessageInfo = SignalDatabase.messages().setOutgoingGiftsRevealed(Collections.singletonList(messageId));
|
||||
if (!markedMessageInfo.isEmpty()) {
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
package org.thoughtcrime.securesms.conversation.v2
|
||||
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.widget.Toast
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.activity.result.contract.ActivityResultContract
|
||||
import androidx.fragment.app.Fragment
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.rxjava3.core.Single
|
||||
import io.reactivex.rxjava3.disposables.Disposable
|
||||
import io.reactivex.rxjava3.kotlin.subscribeBy
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.contactshare.Contact
|
||||
import org.thoughtcrime.securesms.contactshare.ContactUtil
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
|
||||
import org.thoughtcrime.securesms.jobs.DirectoryRefreshJob
|
||||
|
||||
/**
|
||||
* Wraps up the "Add shared contact to contact list" into a contract. The flow here is a little
|
||||
* weird because buildAddToContactsIntent has to be run in the background (as it loads image data).
|
||||
*
|
||||
* Usage:
|
||||
* Register for result from your fragment, and then pass the created launcher in when you call
|
||||
* createIntentAndLaunch.
|
||||
*/
|
||||
class AddToContactsContract : ActivityResultContract<Intent, Unit>() {
|
||||
override fun createIntent(context: Context, input: Intent): Intent = input
|
||||
|
||||
override fun parseResult(resultCode: Int, intent: Intent?) {
|
||||
ApplicationDependencies.getJobManager().add(DirectoryRefreshJob(false))
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private val TAG = Log.tag(AddToContactsContract::class.java)
|
||||
|
||||
@JvmStatic
|
||||
fun createIntentAndLaunch(
|
||||
fragment: Fragment,
|
||||
launcher: ActivityResultLauncher<Intent>,
|
||||
contact: Contact
|
||||
): Disposable {
|
||||
return Single.fromCallable { ContactUtil.buildAddToContactsIntent(fragment.requireContext(), contact) }
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribeBy {
|
||||
try {
|
||||
launcher.launch(it)
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
Log.w(TAG, "Could not locate contacts activity", e)
|
||||
Toast.makeText(fragment.requireContext(), R.string.ConversationFragment__contacts_app_not_found, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,14 @@
|
||||
package org.thoughtcrime.securesms.conversation.v2
|
||||
|
||||
import android.app.ActivityOptions
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.app.ActivityOptionsCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
@@ -14,6 +18,8 @@ import androidx.lifecycle.DefaultLifecycleObserver
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.transition.platform.MaterialContainerTransformSharedElementCallback
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.rxjava3.core.Observable
|
||||
import io.reactivex.rxjava3.core.Single
|
||||
@@ -24,6 +30,8 @@ import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.LoggingFragment
|
||||
import org.thoughtcrime.securesms.MainActivity
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.badges.gifts.viewgift.received.ViewReceivedGiftBottomSheet
|
||||
import org.thoughtcrime.securesms.badges.gifts.viewgift.sent.ViewSentGiftBottomSheet
|
||||
import org.thoughtcrime.securesms.components.ViewBinderDelegate
|
||||
import org.thoughtcrime.securesms.components.recyclerview.SmoothScrollingLinearLayoutManager
|
||||
import org.thoughtcrime.securesms.components.voice.VoiceNoteMediaControllerOwner
|
||||
@@ -55,12 +63,18 @@ import org.thoughtcrime.securesms.giph.mp4.GiphyMp4ProjectionPlayerHolder
|
||||
import org.thoughtcrime.securesms.giph.mp4.GiphyMp4ProjectionRecycler
|
||||
import org.thoughtcrime.securesms.groups.GroupId
|
||||
import org.thoughtcrime.securesms.groups.GroupMigrationMembershipChange
|
||||
import org.thoughtcrime.securesms.groups.ui.GroupErrors
|
||||
import org.thoughtcrime.securesms.groups.v2.GroupBlockJoinRequestResult
|
||||
import org.thoughtcrime.securesms.invites.InviteActions
|
||||
import org.thoughtcrime.securesms.linkpreview.LinkPreview
|
||||
import org.thoughtcrime.securesms.longmessage.LongMessageFragment
|
||||
import org.thoughtcrime.securesms.mediapreview.MediaIntentFactory
|
||||
import org.thoughtcrime.securesms.mediapreview.MediaIntentFactory.create
|
||||
import org.thoughtcrime.securesms.mediapreview.MediaPreviewV2Activity
|
||||
import org.thoughtcrime.securesms.mms.AttachmentManager
|
||||
import org.thoughtcrime.securesms.mms.GlideApp
|
||||
import org.thoughtcrime.securesms.notifications.v2.ConversationId
|
||||
import org.thoughtcrime.securesms.payments.preferences.PaymentsActivity
|
||||
import org.thoughtcrime.securesms.ratelimit.RecaptchaProofBottomSheetFragment
|
||||
import org.thoughtcrime.securesms.reactions.ReactionsBottomSheetDialogFragment
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
@@ -69,12 +83,14 @@ import org.thoughtcrime.securesms.recipients.ui.bottomsheet.RecipientBottomSheet
|
||||
import org.thoughtcrime.securesms.safety.SafetyNumberBottomSheet
|
||||
import org.thoughtcrime.securesms.stickers.StickerLocator
|
||||
import org.thoughtcrime.securesms.stickers.StickerPackPreviewActivity
|
||||
import org.thoughtcrime.securesms.util.BottomSheetUtil
|
||||
import org.thoughtcrime.securesms.util.CommunicationActions
|
||||
import org.thoughtcrime.securesms.util.ContextUtil
|
||||
import org.thoughtcrime.securesms.util.DrawableUtil
|
||||
import org.thoughtcrime.securesms.util.FullscreenHelper
|
||||
import org.thoughtcrime.securesms.util.WindowUtil
|
||||
import org.thoughtcrime.securesms.util.fragments.requireListener
|
||||
import org.thoughtcrime.securesms.util.hasGiftBadge
|
||||
import org.thoughtcrime.securesms.util.visible
|
||||
import org.thoughtcrime.securesms.wallpaper.ChatWallpaper
|
||||
import org.thoughtcrime.securesms.wallpaper.ChatWallpaperDimLevelUtil
|
||||
@@ -117,8 +133,12 @@ class ConversationFragment : LoggingFragment(R.layout.v2_conversation_fragment)
|
||||
private lateinit var conversationOptionsMenuProvider: ConversationOptionsMenu.Provider
|
||||
private lateinit var layoutManager: SmoothScrollingLinearLayoutManager
|
||||
private lateinit var markReadHelper: MarkReadHelper
|
||||
private lateinit var giphyMp4ProjectionRecycler: GiphyMp4ProjectionRecycler
|
||||
private lateinit var addToContactsLauncher: ActivityResultLauncher<Intent>
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
registerForResults()
|
||||
|
||||
conversationOptionsMenuProvider = ConversationOptionsMenu.Provider(ConversationOptionsMenuCallback(), disposables)
|
||||
markReadHelper = MarkReadHelper(ConversationId.forConversation(args.threadId), requireContext(), viewLifecycleOwner)
|
||||
|
||||
@@ -166,6 +186,10 @@ class ConversationFragment : LoggingFragment(R.layout.v2_conversation_fragment)
|
||||
groupCallViewModel.peekGroupCall()
|
||||
}
|
||||
|
||||
private fun registerForResults() {
|
||||
addToContactsLauncher = registerForActivityResult(AddToContactsContract()) {}
|
||||
}
|
||||
|
||||
private fun onFirstRecipientLoad(recipient: Recipient) {
|
||||
Log.d(TAG, "onFirstRecipientLoad")
|
||||
|
||||
@@ -183,7 +207,7 @@ class ConversationFragment : LoggingFragment(R.layout.v2_conversation_fragment)
|
||||
adapter.setPagingController(viewModel.pagingController)
|
||||
viewLifecycleOwner.lifecycle.addObserver(LastSeenPositionUpdater(adapter, layoutManager, viewModel))
|
||||
binding.conversationItemRecycler.adapter = adapter
|
||||
initializeGiphyMp4()
|
||||
giphyMp4ProjectionRecycler = initializeGiphyMp4()
|
||||
|
||||
binding.conversationItemRecycler.addItemDecoration(
|
||||
MultiselectItemDecoration(
|
||||
@@ -266,7 +290,7 @@ class ConversationFragment : LoggingFragment(R.layout.v2_conversation_fragment)
|
||||
}
|
||||
|
||||
disposables += groupCallViewModel.hasActiveGroupCall.subscribeBy(onNext = {
|
||||
// invalidateOptionsMenu
|
||||
invalidateOptionsMenu()
|
||||
binding.conversationGroupCallJoin.visible = it
|
||||
})
|
||||
|
||||
@@ -296,6 +320,17 @@ class ConversationFragment : LoggingFragment(R.layout.v2_conversation_fragment)
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleBlockJoinRequest(recipient: Recipient) {
|
||||
disposables += conversationGroupViewModel.blockJoinRequests(recipient).subscribeBy { result ->
|
||||
if (result.isFailure()) {
|
||||
val failureReason = GroupErrors.getUserDisplayMessage((result as GroupBlockJoinRequestResult.Failure).reason)
|
||||
Toast.makeText(requireContext(), failureReason, Toast.LENGTH_SHORT).show()
|
||||
} else {
|
||||
Toast.makeText(requireContext(), R.string.ConversationFragment__blocked, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getVoiceNoteMediaController() = requireListener<VoiceNoteMediaControllerOwner>().voiceNoteMediaController
|
||||
|
||||
private fun initializeGiphyMp4(): GiphyMp4ProjectionRecycler {
|
||||
@@ -309,13 +344,15 @@ class ConversationFragment : LoggingFragment(R.layout.v2_conversation_fragment)
|
||||
|
||||
val callback = GiphyMp4ProjectionRecycler(holders)
|
||||
GiphyMp4PlaybackController.attach(binding.conversationItemRecycler, callback, maxPlayback)
|
||||
binding.conversationItemRecycler.addItemDecoration(GiphyMp4ItemDecoration(callback) { translationY: Float ->
|
||||
// TODO [alex] reactionsShade.setTranslationY(translationY + list.getHeight())
|
||||
}, 0)
|
||||
binding.conversationItemRecycler.addItemDecoration(
|
||||
GiphyMp4ItemDecoration(callback) { translationY: Float ->
|
||||
// TODO [alex] reactionsShade.setTranslationY(translationY + list.getHeight())
|
||||
},
|
||||
0
|
||||
)
|
||||
return callback
|
||||
}
|
||||
|
||||
|
||||
private inner class ConversationItemClickListener : ConversationAdapter.ItemClickListener {
|
||||
override fun onQuoteClicked(messageRecord: MmsMessageRecord?) {
|
||||
// TODO [alex] - ("Not yet implemented")
|
||||
@@ -352,7 +389,11 @@ class ConversationFragment : LoggingFragment(R.layout.v2_conversation_fragment)
|
||||
}
|
||||
|
||||
override fun onAddToContactsClicked(contact: Contact) {
|
||||
// TODO [alex] - ("Not yet implemented")
|
||||
disposables += AddToContactsContract.createIntentAndLaunch(
|
||||
this@ConversationFragment,
|
||||
addToContactsLauncher,
|
||||
contact
|
||||
)
|
||||
}
|
||||
|
||||
override fun onMessageSharedContactClicked(choices: MutableList<Recipient>) {
|
||||
@@ -374,12 +415,12 @@ class ConversationFragment : LoggingFragment(R.layout.v2_conversation_fragment)
|
||||
}
|
||||
|
||||
override fun onReactionClicked(multiselectPart: MultiselectPart, messageId: Long, isMms: Boolean) {
|
||||
parentFragment ?: return
|
||||
context ?: return
|
||||
ReactionsBottomSheetDialogFragment.create(messageId, isMms).show(parentFragmentManager, null)
|
||||
}
|
||||
|
||||
override fun onGroupMemberClicked(recipientId: RecipientId, groupId: GroupId) {
|
||||
parentFragment ?: return
|
||||
context ?: return
|
||||
RecipientBottomSheetDialogFragment.create(recipientId, groupId).show(parentFragmentManager, "BOTTOM")
|
||||
}
|
||||
|
||||
@@ -476,11 +517,21 @@ class ConversationFragment : LoggingFragment(R.layout.v2_conversation_fragment)
|
||||
}
|
||||
|
||||
override fun onBlockJoinRequest(recipient: Recipient) {
|
||||
// TODO [alex] - ("Not yet implemented")
|
||||
MaterialAlertDialogBuilder(requireContext()).setTitle(R.string.ConversationFragment__block_request)
|
||||
.setMessage(getString(R.string.ConversationFragment__s_will_not_be_able_to_join_or_request_to_join_this_group_via_the_group_link, recipient.getDisplayName(requireContext())))
|
||||
.setNegativeButton(R.string.ConversationFragment__cancel, null)
|
||||
.setPositiveButton(R.string.ConversationFragment__block_request_button) { _, _ -> handleBlockJoinRequest(recipient) }
|
||||
.show()
|
||||
}
|
||||
|
||||
override fun onRecipientNameClicked(target: RecipientId) {
|
||||
// TODO [alex] ("Not yet implemented")
|
||||
context ?: return
|
||||
disposables += viewModel.recipient.firstOrError().observeOn(AndroidSchedulers.mainThread()).subscribeBy {
|
||||
RecipientBottomSheetDialogFragment.create(
|
||||
target,
|
||||
it.groupId.orElse(null)
|
||||
).show(parentFragmentManager, BottomSheetUtil.STANDARD_BOTTOM_SHEET_FRAGMENT_TAG)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onInviteToSignalClicked() {
|
||||
@@ -494,11 +545,16 @@ class ConversationFragment : LoggingFragment(R.layout.v2_conversation_fragment)
|
||||
}
|
||||
|
||||
override fun onActivatePaymentsClicked() {
|
||||
// TODO [alex] -- ("Not yet implemented")
|
||||
startActivity(Intent(requireContext(), PaymentsActivity::class.java))
|
||||
}
|
||||
|
||||
override fun onSendPaymentClicked(recipientId: RecipientId) {
|
||||
// TODO [alex] -- ("Not yet implemented")
|
||||
disposables += viewModel.recipient
|
||||
.firstOrError()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribeBy {
|
||||
AttachmentManager.selectPayment(this@ConversationFragment, it)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onScheduledIndicatorClicked(view: View, messageRecord: MessageRecord) {
|
||||
@@ -511,15 +567,40 @@ class ConversationFragment : LoggingFragment(R.layout.v2_conversation_fragment)
|
||||
}
|
||||
|
||||
override fun onViewGiftBadgeClicked(messageRecord: MessageRecord) {
|
||||
// TODO [alex] -- ("Not yet implemented")
|
||||
if (!messageRecord.hasGiftBadge()) {
|
||||
return
|
||||
}
|
||||
|
||||
if (messageRecord.isOutgoing) {
|
||||
ViewSentGiftBottomSheet.show(childFragmentManager, (messageRecord as MmsMessageRecord))
|
||||
} else {
|
||||
ViewReceivedGiftBottomSheet.show(childFragmentManager, (messageRecord as MmsMessageRecord))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onGiftBadgeRevealed(messageRecord: MessageRecord) {
|
||||
// TODO [alex] -- ("Not yet implemented")
|
||||
viewModel.markGiftBadgeRevealed(messageRecord)
|
||||
}
|
||||
|
||||
override fun goToMediaPreview(parent: ConversationItem?, sharedElement: View?, args: MediaIntentFactory.MediaPreviewArgs?) {
|
||||
// TODO [alex] -- ("Not yet implemented")
|
||||
override fun goToMediaPreview(parent: ConversationItem, sharedElement: View, args: MediaIntentFactory.MediaPreviewArgs) {
|
||||
if (this@ConversationFragment.args.conversationScreenType.isInBubble) {
|
||||
requireActivity().startActivity(create(requireActivity(), args.skipSharedElementTransition(true)))
|
||||
return
|
||||
}
|
||||
|
||||
if (args.isVideoGif) {
|
||||
val adapterPosition: Int = binding.conversationItemRecycler.getChildAdapterPosition(parent)
|
||||
val holder: GiphyMp4ProjectionPlayerHolder? = giphyMp4ProjectionRecycler.getCurrentHolder(adapterPosition)
|
||||
if (holder != null) {
|
||||
parent.showProjectionArea()
|
||||
holder.hide()
|
||||
}
|
||||
}
|
||||
|
||||
sharedElement.transitionName = MediaPreviewV2Activity.SHARED_ELEMENT_TRANSITION_NAME
|
||||
requireActivity().setExitSharedElementCallback(MaterialContainerTransformSharedElementCallback())
|
||||
val options = ActivityOptions.makeSceneTransitionAnimation(requireActivity(), sharedElement, MediaPreviewV2Activity.SHARED_ELEMENT_TRANSITION_NAME)
|
||||
requireActivity().startActivity(create(requireActivity(), args), options.toBundle())
|
||||
}
|
||||
|
||||
override fun onItemClick(item: MultiselectPart?) {
|
||||
|
||||
@@ -124,4 +124,8 @@ class ConversationRepository(context: Context) {
|
||||
fun setLastVisibleMessageTimestamp(threadId: Long, lastVisibleMessageTimestamp: Long) {
|
||||
SignalExecutors.BOUNDED.submit { threads.setLastScrolled(threadId, lastVisibleMessageTimestamp) }
|
||||
}
|
||||
|
||||
fun markGiftBadgeRevealed(messageId: Long) {
|
||||
oldConversationRepository.markGiftBadgeRevealed(messageId)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,8 +13,10 @@ import org.thoughtcrime.securesms.conversation.ConversationIntents.Args
|
||||
import org.thoughtcrime.securesms.conversation.colors.GroupAuthorNameColorHelper
|
||||
import org.thoughtcrime.securesms.conversation.colors.NameColor
|
||||
import org.thoughtcrime.securesms.database.model.MessageId
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||
import org.thoughtcrime.securesms.util.hasGiftBadge
|
||||
import org.thoughtcrime.securesms.wallpaper.ChatWallpaper
|
||||
|
||||
/**
|
||||
@@ -67,6 +69,12 @@ class ConversationViewModel(
|
||||
)
|
||||
}
|
||||
|
||||
fun markGiftBadgeRevealed(messageRecord: MessageRecord) {
|
||||
if (messageRecord.isOutgoing && messageRecord.hasGiftBadge()) {
|
||||
repository.markGiftBadgeRevealed(messageRecord.id)
|
||||
}
|
||||
}
|
||||
|
||||
class Factory(
|
||||
private val args: Args,
|
||||
private val repository: ConversationRepository
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.thoughtcrime.securesms.conversation.v2.groups
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.rxjava3.core.Observable
|
||||
import io.reactivex.rxjava3.core.Single
|
||||
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||
@@ -14,6 +15,8 @@ import org.thoughtcrime.securesms.database.GroupTable
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase
|
||||
import org.thoughtcrime.securesms.database.model.GroupRecord
|
||||
import org.thoughtcrime.securesms.groups.GroupsV1MigrationUtil
|
||||
import org.thoughtcrime.securesms.groups.v2.GroupBlockJoinRequestResult
|
||||
import org.thoughtcrime.securesms.groups.v2.GroupManagementRepository
|
||||
import org.thoughtcrime.securesms.profiles.spoofing.ReviewUtil
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||
@@ -22,7 +25,8 @@ import org.thoughtcrime.securesms.recipients.RecipientId
|
||||
* Manages group state and actions for conversations.
|
||||
*/
|
||||
class ConversationGroupViewModel(
|
||||
private val threadId: Long
|
||||
private val threadId: Long,
|
||||
private val groupManagementRepository: GroupManagementRepository = GroupManagementRepository()
|
||||
) : ViewModel() {
|
||||
|
||||
private val disposables = CompositeDisposable()
|
||||
@@ -83,6 +87,12 @@ class ConversationGroupViewModel(
|
||||
return memberLevel.groupTableMemberLevel != GroupTable.MemberLevel.ADMINISTRATOR && memberLevel.isAnnouncementGroup
|
||||
}
|
||||
|
||||
fun blockJoinRequests(recipient: Recipient): Single<GroupBlockJoinRequestResult> {
|
||||
return _recipient.firstOrError().flatMap {
|
||||
groupManagementRepository.blockJoinRequests(it.requireGroupId().requireV2(), recipient)
|
||||
}.observeOn(AndroidSchedulers.mainThread())
|
||||
}
|
||||
|
||||
private fun getActionableRequestingMembersCount(groupRecord: GroupRecord): Int {
|
||||
return if (groupRecord.isV2Group && groupRecord.memberLevel(Recipient.self()) == GroupTable.MemberLevel.ADMINISTRATOR) {
|
||||
groupRecord.requireV2GroupProperties()
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<org.thoughtcrime.securesms.components.InputPanel xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
tools:viewBindingIgnore="true"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/bottom_panel"
|
||||
android:layout_width="match_parent"
|
||||
|
||||
Reference in New Issue
Block a user