diff --git a/apps/flipcash/app/src/main/kotlin/com/flipcash/app/MainActivity.kt b/apps/flipcash/app/src/main/kotlin/com/flipcash/app/MainActivity.kt index 77f4e6fec..17839396b 100644 --- a/apps/flipcash/app/src/main/kotlin/com/flipcash/app/MainActivity.kt +++ b/apps/flipcash/app/src/main/kotlin/com/flipcash/app/MainActivity.kt @@ -192,12 +192,12 @@ class MainActivity : FragmentActivity() { /** * Test-only: enable beta flags passed as a launch argument, so flag-gated features - * (blocklist, …) can be exercised in UI tests without toggling them in the - * Labs UI. Mirrors iOS's `--beta-flags`. Debug/UI-test builds only. + * can be exercised in UI tests without toggling them in the Labs UI. Mirrors iOS's + * `--beta-flags`. Debug/UI-test builds only. * * launchApp: * arguments: - * betaFlags: "blocklist_enabled" + * betaFlags: "coinbase_onramp_sandbox_enabled" * * The value is a comma-separated list of [FeatureFlag.key]s. */ diff --git a/apps/flipcash/features/messenger/src/main/kotlin/com/flipcash/app/messenger/internal/ChatViewModel.kt b/apps/flipcash/features/messenger/src/main/kotlin/com/flipcash/app/messenger/internal/ChatViewModel.kt index 4b1341b9d..f59ef68d4 100644 --- a/apps/flipcash/features/messenger/src/main/kotlin/com/flipcash/app/messenger/internal/ChatViewModel.kt +++ b/apps/flipcash/features/messenger/src/main/kotlin/com/flipcash/app/messenger/internal/ChatViewModel.kt @@ -16,8 +16,6 @@ import com.flipcash.app.core.chat.ChatIdentifier import com.flipcash.app.core.chat.ChatParticipant import com.flipcash.app.core.contacts.DeviceContact import com.flipcash.app.core.ui.ConfirmationStyle -import com.flipcash.app.featureflags.FeatureFlag -import com.flipcash.app.featureflags.FeatureFlagController import com.flipcash.shared.chat.models.ChatListItem import com.flipcash.shared.chat.models.ReceiptStatus import com.flipcash.shared.chat.models.SeparatorConfig @@ -104,7 +102,6 @@ internal class ChatViewModel @Inject constructor( private val purchaseMethodController: PurchaseMethodController, private val userManager: UserManager, private val resources: ResourceHelper, - private val featureFlags: FeatureFlagController, private val analytics: FlipcashAnalyticsService, ) : BaseViewModel( initialState = State(), @@ -147,14 +144,10 @@ internal class ChatViewModel @Inject constructor( // open would be missed by the bottom bar before it subscribes, whereas state is durable // until the input is actually composed and can consume it. val messageInputRequested: Boolean = false, - // Whether the Blocklist beta flag is enabled. Backs canViewProfile; observed in init. - val blocklistEnabled: Boolean = false, ) { - // Opening the participant's profile (the entry point to blocking) is only available for tip - // DMs, and only when the Blocklist beta flag is on. Derived so it stays correct regardless - // of whether the flag or the chat type resolves first. + // Opening the participant's profile (the entry point to blocking) is only available for tip DMs. val canViewProfile: Boolean - get() = blocklistEnabled && chatType == ChatType.TIP_DM + get() = chatType == ChatType.TIP_DM } sealed interface Event { @@ -199,7 +192,6 @@ internal class ChatViewModel @Inject constructor( data class LimitsChanged(val limits: Limits?) : Event data class AdvanceReadPointer(val messageId: Long) : Event data class ChatDeactivated(val isReadOnly: Boolean) : Event - data class BlocklistEnabledChanged(val enabled: Boolean) : Event } @OptIn(ExperimentalCoroutinesApi::class) @@ -444,10 +436,6 @@ internal class ChatViewModel @Inject constructor( .onEach { dispatchEvent(Event.ChatDeactivated(isReadOnly = it)) } .launchIn(viewModelScope) - featureFlags.observe(FeatureFlag.Blocklist) - .onEach { dispatchEvent(Event.BlocklistEnabledChanged(it)) } - .launchIn(viewModelScope) - // Advance read pointer when user scrolls to messages eventFlow .filterIsInstance() @@ -916,7 +904,6 @@ internal class ChatViewModel @Inject constructor( is Event.LimitsChanged -> { state -> state.copy(limits = event.limits) } is Event.AdvanceReadPointer -> { state -> state } is Event.ChatDeactivated -> { state -> state.copy(isAnonymous = event.isReadOnly) } - is Event.BlocklistEnabledChanged -> { state -> state.copy(blocklistEnabled = event.enabled) } } } } diff --git a/apps/flipcash/features/messenger/src/main/kotlin/com/flipcash/app/messenger/internal/screens/MessengerScreen.kt b/apps/flipcash/features/messenger/src/main/kotlin/com/flipcash/app/messenger/internal/screens/MessengerScreen.kt index ad61b45ff..5b708fad5 100644 --- a/apps/flipcash/features/messenger/src/main/kotlin/com/flipcash/app/messenger/internal/screens/MessengerScreen.kt +++ b/apps/flipcash/features/messenger/src/main/kotlin/com/flipcash/app/messenger/internal/screens/MessengerScreen.kt @@ -62,8 +62,8 @@ internal fun MessengerScreen(viewModel: ChatViewModel) { } is ChatAction.ViewProfile -> { - // The triggers (top-bar tap, contact-card chevron) are only clickable when the - // Blocklist beta flag is on, so no gating is needed here. + // The triggers (top-bar tap, contact-card chevron) are only clickable for tip DMs + // (see State.canViewProfile), so no gating is needed here. state.participant?.let { keyboard.hideIfVisible { navigator.push(ChatStep.Profile(it)) diff --git a/apps/flipcash/features/messenger/src/main/kotlin/com/flipcash/app/messenger/internal/screens/components/ChatTopBar.kt b/apps/flipcash/features/messenger/src/main/kotlin/com/flipcash/app/messenger/internal/screens/components/ChatTopBar.kt index 2486b440c..4543ddc97 100644 --- a/apps/flipcash/features/messenger/src/main/kotlin/com/flipcash/app/messenger/internal/screens/components/ChatTopBar.kt +++ b/apps/flipcash/features/messenger/src/main/kotlin/com/flipcash/app/messenger/internal/screens/components/ChatTopBar.kt @@ -59,7 +59,7 @@ internal fun ChatTopBar( }, title = { Row( - // Profile open is gated behind the Blocklist beta flag. + // Profile open is only available for tip DMs (see State.canViewProfile). modifier = Modifier .fillMaxWidth() .then( diff --git a/apps/flipcash/features/messenger/src/main/kotlin/com/flipcash/app/messenger/internal/screens/components/MessageList.kt b/apps/flipcash/features/messenger/src/main/kotlin/com/flipcash/app/messenger/internal/screens/components/MessageList.kt index db02e531d..cea1b61ad 100644 --- a/apps/flipcash/features/messenger/src/main/kotlin/com/flipcash/app/messenger/internal/screens/components/MessageList.kt +++ b/apps/flipcash/features/messenger/src/main/kotlin/com/flipcash/app/messenger/internal/screens/components/MessageList.kt @@ -278,7 +278,7 @@ internal fun MessageList( .fillMaxWidth(0.63f), onRefreshContact = { onAction(ChatAction.RefreshContact) }, // null hides the chevron and makes the card non-tappable when the - // Blocklist beta flag is off. + // profile isn't viewable (non-tip-DM chats). onOpenProfile = if (canViewProfile) { { onAction(ChatAction.ViewProfile) } } else { diff --git a/apps/flipcash/features/myaccount/src/main/kotlin/com/flipcash/app/myaccount/internal/myaccount/MyAccountMenuItems.kt b/apps/flipcash/features/myaccount/src/main/kotlin/com/flipcash/app/myaccount/internal/myaccount/MyAccountMenuItems.kt index c7e65d809..4d6c3ad96 100644 --- a/apps/flipcash/features/myaccount/src/main/kotlin/com/flipcash/app/myaccount/internal/myaccount/MyAccountMenuItems.kt +++ b/apps/flipcash/features/myaccount/src/main/kotlin/com/flipcash/app/myaccount/internal/myaccount/MyAccountMenuItems.kt @@ -9,7 +9,6 @@ import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.rememberVectorPainter import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource -import com.flipcash.app.featureflags.FeatureFlag import com.flipcash.app.menu.FullMenuItem import com.flipcash.app.menu.StaffMenuItem import com.flipcash.core.R as CoreR @@ -24,9 +23,7 @@ internal data object AccessKey : FullMenuItem() override val action: MyAccountScreenViewModel.Event = MyAccountScreenViewModel.Event.OnAccessKeyClicked } -internal data object Blocklist : FullMenuItem( - featureFlag = FeatureFlag.Blocklist, -) { +internal data object Blocklist : FullMenuItem() { override val icon: Painter @Composable get() = rememberVectorPainter(Icons.Outlined.Block) override val name: String diff --git a/apps/flipcash/features/myaccount/src/main/kotlin/com/flipcash/app/myaccount/internal/myaccount/MyAccountScreenViewModel.kt b/apps/flipcash/features/myaccount/src/main/kotlin/com/flipcash/app/myaccount/internal/myaccount/MyAccountScreenViewModel.kt index 4355c1cf5..745d0500c 100644 --- a/apps/flipcash/features/myaccount/src/main/kotlin/com/flipcash/app/myaccount/internal/myaccount/MyAccountScreenViewModel.kt +++ b/apps/flipcash/features/myaccount/src/main/kotlin/com/flipcash/app/myaccount/internal/myaccount/MyAccountScreenViewModel.kt @@ -46,7 +46,7 @@ internal class MyAccountScreenViewModel @Inject constructor( internal data class State( val isBetaEnabled: Boolean = false, // Default hides staff-only AND flag-gated items until the real flag state loads, so a - // beta-gated item (e.g. Blocklist) never flashes before its flag is resolved. + // beta-gated item never flashes before its flag is resolved. val items: List> = FullMenuList.filterNot { it is StaffMenuItem || it.featureFlag != null } ) @@ -169,7 +169,7 @@ internal class MyAccountScreenViewModel @Inject constructor( } else { FullMenuList.filterNot { item -> item is StaffMenuItem } } - // Flag-gated items (e.g. Blocklist) only show when their feature flag is enabled. + // Flag-gated items only show when their feature flag is enabled. return base.filter { item -> val flag = item.featureFlag ?: return@filter true flags.find { it.flag.key == flag.key }?.enabled == true diff --git a/apps/flipcash/shared/featureflags/src/main/kotlin/com/flipcash/app/featureflags/FeatureFlag.kt b/apps/flipcash/shared/featureflags/src/main/kotlin/com/flipcash/app/featureflags/FeatureFlag.kt index 733acaa5c..b9cd1cc4f 100644 --- a/apps/flipcash/shared/featureflags/src/main/kotlin/com/flipcash/app/featureflags/FeatureFlag.kt +++ b/apps/flipcash/shared/featureflags/src/main/kotlin/com/flipcash/app/featureflags/FeatureFlag.kt @@ -138,15 +138,6 @@ sealed interface FeatureFlag { override val persistLogOut: Boolean = false } - @FeatureFlagMarker - data object Blocklist: FeatureFlag { - override val key: String = "blocklist_enabled" - override val default: Boolean = false - override val launched: Boolean = false - override val visible: Boolean = true - override val persistLogOut: Boolean = false - } - companion object { val entries: List> get() = FeatureFlagEntries.entries @@ -171,7 +162,6 @@ val FeatureFlag<*>.title: String FeatureFlag.GiveUsdf -> "Give/Send USDF" FeatureFlag.ShowNetworkState -> "Network Offline Indicator" FeatureFlag.FrostedTipCard -> "Frosted Tip Card" - FeatureFlag.Blocklist -> "Blocklist" } val FeatureFlag<*>.message: String @@ -187,7 +177,6 @@ val FeatureFlag<*>.message: String FeatureFlag.GiveUsdf -> "When enabled, you'll gain the ability to send USDF directly and give it as cash" FeatureFlag.ShowNetworkState -> "When enabled, you'll gain the ability to see the network state on the Scanner when offline" FeatureFlag.FrostedTipCard -> "When enabled, the tip card in the scanner renders as frosted glass over a blurred snapshot of the camera instead of a solid card" - FeatureFlag.Blocklist -> "When enabled, you'll gain the ability to open a chat participant's profile, block them, and manage your blocklist from My Account" } diff --git a/maestro/blocking.yaml b/maestro/blocking.yaml index 11bb13ff4..4cf1490ce 100644 --- a/maestro/blocking.yaml +++ b/maestro/blocking.yaml @@ -3,11 +3,11 @@ name: "Blocking — block & unblock a chat participant" tags: - blocklist --- -# Tipping is on by default (to reach the tip chat); enable blocklist at launch. +# Tipping and blocking are on by default; no beta flags needed to reach the tip chat. - runFlow: file: subflows/login_with_flags.yaml env: - BETA_FLAGS: "blocklist_enabled" + BETA_FLAGS: "" # Open the tip conversation. - tapOn: "Tips"