Add support for conversation intent routing to MainActivity.

This commit is contained in:
Alex Hart
2025-04-24 12:24:24 -03:00
committed by Cody Henthorne
parent 9d593bcaff
commit ae90b2ecd9
9 changed files with 72 additions and 24 deletions

View File

@@ -10,12 +10,14 @@ import androidx.annotation.MainThread;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.MainActivity;
import org.thoughtcrime.securesms.badges.models.Badge;
import org.thoughtcrime.securesms.conversation.colors.ChatColors;
import org.thoughtcrime.securesms.conversation.v2.ConversationActivity;
import org.thoughtcrime.securesms.database.SignalDatabase;
import org.thoughtcrime.securesms.database.ThreadTable;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.main.MainNavigationListLocation;
import org.thoughtcrime.securesms.mediasend.Media;
import org.thoughtcrime.securesms.mms.SlideFactory;
import org.thoughtcrime.securesms.recipients.Recipient;
@@ -34,7 +36,7 @@ import io.reactivex.rxjava3.core.Single;
import io.reactivex.rxjava3.schedulers.Schedulers;
public class ConversationIntents {
private static final String TAG = Log.tag(ConversationIntents.class);
private static final String ACTION = "ConversationIntents.ViewConversation";
private static final String BUBBLE_AUTHORITY = "bubble";
private static final String NOTIFICATION_CUSTOM_SCHEME = "custom";
@@ -97,7 +99,11 @@ public class ConversationIntents {
*/
public static @NonNull Builder createBuilderSync(@NonNull Context context, @NonNull RecipientId recipientId, long threadId) {
Preconditions.checkArgument(threadId > 0, "threadId is invalid");
return new Builder(context, ConversationActivity.class, recipientId, threadId, ConversationScreenType.NORMAL);
return new Builder(context, getConversationActivityClass(), recipientId, threadId, ConversationScreenType.NORMAL);
}
private static @NonNull Class<? extends Activity> getConversationActivityClass() {
return SignalStore.internal().getLargeScreenUi() ? MainActivity.class : ConversationActivity.class;
}
static @Nullable Uri getIntentData(@NonNull Bundle bundle) {
@@ -129,6 +135,10 @@ public class ConversationIntents {
return uri != null && Objects.equals(uri.getScheme(), NOTIFICATION_CUSTOM_SCHEME);
}
public static boolean isConversationIntent(@NonNull Intent intent) {
return ACTION.equals(intent.getAction());
}
public final static class Args {
private final RecipientId recipientId;
private final long threadId;
@@ -393,9 +403,14 @@ public class ConversationIntents {
throw new IllegalStateException("Cannot have both sticker and media array");
}
Intent intent = new Intent(context, conversationActivityClass);
final Intent intent;
if (MainActivity.class.equals(conversationActivityClass)) {
intent = MainActivity.clearTop(context);
} else {
intent = new Intent(context, conversationActivityClass);
}
intent.setAction(Intent.ACTION_DEFAULT);
intent.setAction(ConversationIntents.ACTION);
if (conversationScreenType.isInBubble()) {
intent.setData(new Uri.Builder().authority(BUBBLE_AUTHORITY)

View File

@@ -6,6 +6,7 @@ import android.os.Bundle
import android.view.MotionEvent
import android.view.Window
import androidx.activity.viewModels
import androidx.lifecycle.enableSavedStateHandles
import io.reactivex.rxjava3.subjects.PublishSubject
import io.reactivex.rxjava3.subjects.Subject
import org.signal.core.util.logging.Log
@@ -49,16 +50,12 @@ open class ConversationActivity : PassphraseRequiredActivity(), VoiceNoteMediaCo
}
override fun onCreate(savedInstanceState: Bundle?, ready: Boolean) {
enableSavedStateHandles()
supportPostponeEnterTransition()
transitionDebouncer.publish { supportStartPostponedEnterTransition() }
window.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
if (savedInstanceState != null) {
shareDataTimestampViewModel.timestamp = savedInstanceState.getLong(STATE_WATERMARK, -1L)
} else if (intent.flags and Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY != 0) {
shareDataTimestampViewModel.timestamp = System.currentTimeMillis()
}
shareDataTimestampViewModel.setTimestampFromActivityCreation(savedInstanceState, intent)
setContentView(R.layout.fragment_container)
if (savedInstanceState == null) {
@@ -71,11 +68,6 @@ open class ConversationActivity : PassphraseRequiredActivity(), VoiceNoteMediaCo
theme.onResume(this)
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putLong(STATE_WATERMARK, shareDataTimestampViewModel.timestamp)
}
override fun onStop() {
super.onStop()
if (isChangingConfigurations) {

View File

@@ -1564,7 +1564,7 @@ class ConversationFragment :
}
private fun handleShareOrDraftData(inputReadyState: InputReadyState, data: ShareOrDraftData) {
shareDataTimestampViewModel.timestamp = args.shareDataTimestamp
shareDataTimestampViewModel.setTimestampFromConversationArgs(args)
if (inputReadyState.isAnnouncementGroup == true && inputReadyState.isAdmin == false) {
Toast.makeText(requireContext(), R.string.MultiselectForwardFragment__only_admins_can_send_messages_to_this_group, Toast.LENGTH_SHORT).show()

View File

@@ -5,12 +5,35 @@
package org.thoughtcrime.securesms.conversation.v2
import android.content.Intent
import android.os.Bundle
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import org.thoughtcrime.securesms.conversation.ConversationIntents
import org.thoughtcrime.securesms.util.delegate
/**
* Hold the last share timestamp in an activity scoped view model for sharing between
* the activity and fragments.
*/
class ShareDataTimestampViewModel : ViewModel() {
var timestamp: Long = -1L
class ShareDataTimestampViewModel(
savedStateHandle: SavedStateHandle
) : ViewModel() {
companion object {
private const val TIMESTAMP = "timestamp"
}
var timestamp: Long by savedStateHandle.delegate(TIMESTAMP, -1L)
private set
fun setTimestampFromActivityCreation(savedInstanceState: Bundle?, intent: Intent) {
if (savedInstanceState == null && intent.flags and Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY != 0) {
timestamp = System.currentTimeMillis()
}
}
fun setTimestampFromConversationArgs(args: ConversationIntents.Args) {
timestamp = args.shareDataTimestamp
}
}