From 1b2b4a869c1f367f38b156df63823341211fc0ee Mon Sep 17 00:00:00 2001 From: Cody Henthorne Date: Tue, 22 Oct 2024 12:05:27 -0400 Subject: [PATCH] Add release note CTA action to open Calls tab. --- .../thoughtcrime/securesms/MainActivity.java | 38 +++++++++++++++++-- .../internal/InternalSettingsRepository.kt | 3 ++ .../conversation/v2/ConversationFragment.kt | 3 ++ .../stories/tabs/ConversationListTabsState.kt | 2 +- .../tabs/ConversationListTabsViewModel.kt | 13 +++++-- .../org/signal/core/util/BundleExtensions.kt | 2 + 6 files changed, 53 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/MainActivity.java b/app/src/main/java/org/thoughtcrime/securesms/MainActivity.java index b20699e2bb..d243f86129 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/MainActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/MainActivity.java @@ -16,13 +16,14 @@ import androidx.lifecycle.ViewModelProvider; import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import org.signal.core.util.BundleExtensions; import org.signal.core.util.concurrent.LifecycleDisposable; import org.signal.donations.StripeApi; import org.thoughtcrime.securesms.calls.YouAreAlreadyInACallSnackbar; +import org.thoughtcrime.securesms.components.ConnectivityWarningBottomSheet; import org.thoughtcrime.securesms.components.DebugLogsPromptDialogFragment; import org.thoughtcrime.securesms.components.DeviceSpecificNotificationBottomSheet; import org.thoughtcrime.securesms.components.PromptBatterySaverDialogFragment; -import org.thoughtcrime.securesms.components.ConnectivityWarningBottomSheet; import org.thoughtcrime.securesms.components.settings.app.AppSettingsActivity; import org.thoughtcrime.securesms.components.voice.VoiceNoteMediaController; import org.thoughtcrime.securesms.components.voice.VoiceNoteMediaControllerOwner; @@ -31,6 +32,8 @@ import org.thoughtcrime.securesms.devicetransfer.olddevice.OldDeviceExitActivity import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.net.DeviceTransferBlockingInterceptor; import org.thoughtcrime.securesms.notifications.VitalsViewModel; +import org.thoughtcrime.securesms.stories.Stories; +import org.thoughtcrime.securesms.stories.tabs.ConversationListTab; import org.thoughtcrime.securesms.stories.tabs.ConversationListTabRepository; import org.thoughtcrime.securesms.stories.tabs.ConversationListTabsViewModel; import org.thoughtcrime.securesms.util.AppStartup; @@ -43,7 +46,8 @@ import org.thoughtcrime.securesms.util.WindowUtil; public class MainActivity extends PassphraseRequiredActivity implements VoiceNoteMediaControllerOwner { - public static final int RESULT_CONFIG_CHANGED = Activity.RESULT_FIRST_USER + 901; + private static final String KEY_STARTING_TAB = "STARTING_TAB"; + public static final int RESULT_CONFIG_CHANGED = Activity.RESULT_FIRST_USER + 901; private final DynamicTheme dynamicTheme = new DynamicNoActionBarTheme(); private final MainNavigator navigator = new MainNavigator(this); @@ -66,6 +70,13 @@ public class MainActivity extends PassphraseRequiredActivity implements VoiceNot return intent; } + public static @NonNull Intent clearTopAndOpenTab(@NonNull Context context, @NonNull ConversationListTab startingTab) { + Intent intent = clearTop(context); + intent.putExtra(KEY_STARTING_TAB, startingTab); + + return intent; + } + @Override protected void onCreate(Bundle savedInstanceState, boolean ready) { AppStartup.getInstance().onCriticalRenderEventStart(); @@ -91,8 +102,14 @@ public class MainActivity extends PassphraseRequiredActivity implements VoiceNot mediaController = new VoiceNoteMediaController(this, true); + + ConversationListTab startingTab = null; + if (getIntent().getExtras() != null) { + startingTab = BundleExtensions.getSerializableCompat(getIntent().getExtras(), KEY_STARTING_TAB, ConversationListTab.class); + } + ConversationListTabRepository repository = new ConversationListTabRepository(); - ConversationListTabsViewModel.Factory factory = new ConversationListTabsViewModel.Factory(repository); + ConversationListTabsViewModel.Factory factory = new ConversationListTabsViewModel.Factory(startingTab, repository); handleDeeplinkIntent(getIntent()); @@ -147,6 +164,21 @@ public class MainActivity extends PassphraseRequiredActivity implements VoiceNot protected void onNewIntent(Intent intent) { super.onNewIntent(intent); handleDeeplinkIntent(intent); + + if (intent.getExtras() != null) { + ConversationListTab startingTab = BundleExtensions.getSerializableCompat(intent.getExtras(), KEY_STARTING_TAB, ConversationListTab.class); + if (startingTab != null) { + switch (startingTab) { + case CHATS -> conversationListTabsViewModel.onChatsSelected(); + case CALLS -> conversationListTabsViewModel.onCallsSelected(); + case STORIES -> { + if (Stories.isFeatureEnabled()) { + conversationListTabsViewModel.onStoriesSelected(); + } + } + } + } + } } @Override diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsRepository.kt index 52a29f571c..1c719ee9b5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsRepository.kt @@ -7,6 +7,7 @@ import org.signal.donations.InAppPaymentType import org.thoughtcrime.securesms.database.MessageTable import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.database.model.RemoteMegaphoneRecord +import org.thoughtcrime.securesms.database.model.addButton import org.thoughtcrime.securesms.database.model.addStyle import org.thoughtcrime.securesms.database.model.databaseprotos.BodyRangeList import org.thoughtcrime.securesms.dependencies.AppDependencies @@ -51,6 +52,8 @@ class InternalSettingsRepository(context: Context) { val bodyRangeList = BodyRangeList.Builder() .addStyle(BodyRangeList.BodyRange.Style.BOLD, 0, title.length) + bodyRangeList.addButton("Call to Action Text", "action", body.lastIndex, 0) + val recipientId = SignalStore.releaseChannel.releaseChannelRecipientId!! val threadId = SignalDatabase.threads.getOrCreateThreadIdFor(Recipient.resolved(recipientId)) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt index 7b67553a0f..294231b6e6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt @@ -295,6 +295,7 @@ import org.thoughtcrime.securesms.stickers.StickerManagementActivity import org.thoughtcrime.securesms.stickers.StickerPackInstallEvent import org.thoughtcrime.securesms.stickers.StickerPackPreviewActivity import org.thoughtcrime.securesms.stories.StoryViewerArgs +import org.thoughtcrime.securesms.stories.tabs.ConversationListTab import org.thoughtcrime.securesms.stories.viewer.StoryViewerActivity import org.thoughtcrime.securesms.util.BottomSheetUtil import org.thoughtcrime.securesms.util.BubbleUtil @@ -3018,6 +3019,8 @@ class ConversationFragment : checkoutLauncher.launch(InAppPaymentType.ONE_TIME_GIFT) } else if ("username_edit" == action) { startActivity(EditProfileActivity.getIntentForUsernameEdit(requireContext())) + } else if ("calls_tab" == action) { + startActivity(MainActivity.clearTopAndOpenTab(requireContext(), ConversationListTab.CALLS)) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/tabs/ConversationListTabsState.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/tabs/ConversationListTabsState.kt index e0a71ca174..a7f41bec6f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/tabs/ConversationListTabsState.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/tabs/ConversationListTabsState.kt @@ -2,7 +2,7 @@ package org.thoughtcrime.securesms.stories.tabs data class ConversationListTabsState( val tab: ConversationListTab = ConversationListTab.CHATS, - val prevTab: ConversationListTab = ConversationListTab.STORIES, + val prevTab: ConversationListTab = if (tab == ConversationListTab.CHATS) ConversationListTab.STORIES else ConversationListTab.CHATS, val unreadMessagesCount: Long = 0L, val unreadCallsCount: Long = 0L, val unreadStoriesCount: Long = 0L, diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/tabs/ConversationListTabsViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/tabs/ConversationListTabsViewModel.kt index 3ef421e50a..c5c116256c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/tabs/ConversationListTabsViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/tabs/ConversationListTabsViewModel.kt @@ -13,8 +13,8 @@ import io.reactivex.rxjava3.subjects.Subject import org.thoughtcrime.securesms.stories.Stories import org.thoughtcrime.securesms.util.rx.RxStore -class ConversationListTabsViewModel(repository: ConversationListTabRepository) : ViewModel() { - private val store = RxStore(ConversationListTabsState()) +class ConversationListTabsViewModel(startingTab: ConversationListTab, repository: ConversationListTabRepository) : ViewModel() { + private val store = RxStore(ConversationListTabsState(tab = startingTab)) val stateSnapshot: ConversationListTabsState get() = store.state @@ -94,9 +94,14 @@ class ConversationListTabsViewModel(repository: ConversationListTabRepository) : } } - class Factory(private val repository: ConversationListTabRepository) : ViewModelProvider.Factory { + class Factory(private val startingTab: ConversationListTab?, private val repository: ConversationListTabRepository) : ViewModelProvider.Factory { override fun create(modelClass: Class): T { - return modelClass.cast(ConversationListTabsViewModel(repository)) as T + val tab = if (startingTab == null || (startingTab == ConversationListTab.STORIES && !Stories.isFeatureEnabled())) { + ConversationListTab.CHATS + } else { + startingTab + } + return modelClass.cast(ConversationListTabsViewModel(tab, repository)) as T } } } diff --git a/core-util/src/main/java/org/signal/core/util/BundleExtensions.kt b/core-util/src/main/java/org/signal/core/util/BundleExtensions.kt index 484b2f1e14..e7f488dca8 100644 --- a/core-util/src/main/java/org/signal/core/util/BundleExtensions.kt +++ b/core-util/src/main/java/org/signal/core/util/BundleExtensions.kt @@ -1,3 +1,5 @@ +@file:JvmName("BundleExtensions") + package org.signal.core.util import android.os.Build