From 9e3e227eb16c81169a2e15ed61301f62bff13bc0 Mon Sep 17 00:00:00 2001 From: Brandon McAnsh Date: Mon, 21 Sep 2026 15:36:20 -0400 Subject: [PATCH] chore(scanner): retire the ScanFromGallery flag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The gallery button draws whenever no bill is up, for everyone. The flag defaulted to false and inherited FeatureTrack.Internal, so the feature only ever reached staff with the beta override — it was a rollout gate, and the rollout is the point of removing it. Dropping the observation also takes the scanner's only FeatureFlag reference, so `:apps:flipcash:shared:featureflags` leaves the module's build file with it. The `persistLogOut = true` the flag carried has no successor: the preference key stays in DataStore unread, the same as the other retired flags. --- apps/flipcash/features/scanner/build.gradle.kts | 1 - .../scanner/internal/bills/ScannableContainer.kt | 14 +------------- .../com/flipcash/app/featureflags/FeatureFlag.kt | 16 ---------------- 3 files changed, 1 insertion(+), 30 deletions(-) diff --git a/apps/flipcash/features/scanner/build.gradle.kts b/apps/flipcash/features/scanner/build.gradle.kts index 812002f78e..2ee179eaa5 100644 --- a/apps/flipcash/features/scanner/build.gradle.kts +++ b/apps/flipcash/features/scanner/build.gradle.kts @@ -12,7 +12,6 @@ dependencies { implementation(project(":apps:flipcash:shared:appupdates")) implementation(project(":apps:flipcash:shared:bills")) implementation(project(":apps:flipcash:shared:bill-customization")) - implementation(project(":apps:flipcash:shared:featureflags")) implementation(project(":apps:flipcash:shared:router")) implementation(project(":apps:flipcash:shared:session")) diff --git a/apps/flipcash/features/scanner/src/main/kotlin/com/flipcash/app/scanner/internal/bills/ScannableContainer.kt b/apps/flipcash/features/scanner/src/main/kotlin/com/flipcash/app/scanner/internal/bills/ScannableContainer.kt index 0f75c0acb7..4e12caf92b 100644 --- a/apps/flipcash/features/scanner/src/main/kotlin/com/flipcash/app/scanner/internal/bills/ScannableContainer.kt +++ b/apps/flipcash/features/scanner/src/main/kotlin/com/flipcash/app/scanner/internal/bills/ScannableContainer.kt @@ -9,7 +9,6 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -18,8 +17,6 @@ import androidx.compose.ui.platform.LocalResources import androidx.compose.ui.platform.testTag import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.flipcash.app.core.android.extensions.launchAppSettings -import com.flipcash.app.featureflags.FeatureFlag -import com.flipcash.app.featureflags.LocalFeatureFlags import com.flipcash.app.scanner.internal.GalleryScanButton import com.flipcash.app.session.LocalSessionController import com.flipcash.app.updates.LocalAppUpdater @@ -124,15 +121,6 @@ internal fun ScannableContainer( } } - // Remembered because `observe` builds a fresh `stateIn(dataScope, Eagerly, ..)` on every - // call and `dataScope` outlives the screen: calling it straight from a composable body - // starts a DataStore collection per recomposition that nothing ever cancels. - val featureFlags = LocalFeatureFlags.current - val galleryFlag = remember(featureFlags) { - featureFlags.observe(FeatureFlag.ScanFromGallery) - } - val galleryEnabled by galleryFlag.collectAsStateWithLifecycle() - // Outside the permission `when` on purpose: a picked photo needs no camera, and someone // who declined the camera is exactly who this is for. // @@ -140,7 +128,7 @@ internal fun ScannableContainer( // entry's content, so the bill already covers the button -- but leaving it composed under // the scrim means a live control is sitting behind something modal, which is worth not // having rather than relying on the overlay to swallow every touch. - if (galleryEnabled && billState.bill == null) { + if (billState.bill == null) { GalleryScanButton( onImagePicked = onImagePicked, hazeState = hazeState, 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 7cd8ec24c9..a6c13c9dac 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 @@ -107,17 +107,6 @@ sealed interface FeatureFlag { override val persistLogOut: Boolean = false } - @FeatureFlagMarker - data object ScanFromGallery: FeatureFlag { - override val key: String = "scan_from_gallery" - override val default: Boolean = false - override val launched: Boolean = false - override val visible: Boolean = true - // Matches ContactPickerMode: the setting is about how you reach the camera, not about - // the account you reached it with. - override val persistLogOut: Boolean = true - } - companion object { val entries: List> get() = FeatureFlagEntries.entries @@ -139,7 +128,6 @@ val FeatureFlag<*>.title: String FeatureFlag.ContactPickerMode -> "Contact Picker Mode" FeatureFlag.ShowNetworkState -> "Network Offline Indicator" FeatureFlag.FrostedTipCard -> "Frosted Tip Card" - FeatureFlag.ScanFromGallery -> "Scan from Gallery" } val FeatureFlag<*>.message: String @@ -152,8 +140,4 @@ val FeatureFlag<*>.message: String FeatureFlag.ContactPickerMode -> "When enabled, contacts will be accessed via the system contact picker instead of requesting full READ_CONTACTS permission" 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.ScanFromGallery -> "When enabled, the scanner gains a gallery button for searching a photo you already have for a code, for when someone sends you a screenshot instead of showing you their screen" } - - -