diff --git a/app/src/main/java/app/closer/core/billing/CouplePremiumChecker.kt b/app/src/main/java/app/closer/core/billing/CouplePremiumChecker.kt index c1716789..72c5e5a5 100644 --- a/app/src/main/java/app/closer/core/billing/CouplePremiumChecker.kt +++ b/app/src/main/java/app/closer/core/billing/CouplePremiumChecker.kt @@ -2,7 +2,7 @@ package app.closer.core.billing import app.closer.data.remote.FirestoreCollections import app.closer.domain.repository.CoupleRepository -import com.google.firebase.auth.FirebaseAuth +import app.closer.domain.repository.AuthRepository import com.google.firebase.firestore.FirebaseFirestore import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow @@ -29,11 +29,12 @@ import javax.inject.Singleton class CouplePremiumChecker @Inject constructor( private val entitlementChecker: EntitlementChecker, private val firestore: FirebaseFirestore, - private val coupleRepository: CoupleRepository + private val coupleRepository: CoupleRepository, + private val authRepository: AuthRepository ) { /** Couple-shared premium for the current user (resolves the partner internally). Drop-in for EntitlementChecker. */ fun isPremium(): Flow = flow { - val uid = FirebaseAuth.getInstance().currentUser?.uid + val uid = authRepository.currentUserId val partnerId = uid?.let { runCatching { coupleRepository.getCoupleForUser(it)?.userIds?.firstOrNull { id -> id != it } }.getOrNull() } diff --git a/app/src/main/java/app/closer/core/navigation/AppNavigation.kt b/app/src/main/java/app/closer/core/navigation/AppNavigation.kt index 1bad6f8e..77a7d96f 100644 --- a/app/src/main/java/app/closer/core/navigation/AppNavigation.kt +++ b/app/src/main/java/app/closer/core/navigation/AppNavigation.kt @@ -477,9 +477,6 @@ fun AppNavigation( onNavigate = navigateRoute ) } - composable(route = AppRoute.WHEEL_HISTORY) { - GameHistoryScreen(onNavigate = navigateRoute) - } composable(route = AppRoute.GAME_HISTORY) { GameHistoryScreen(onNavigate = navigateRoute) } @@ -604,11 +601,14 @@ fun AppNavigation( composable(route = AppRoute.ACTIVITY) { ActivityScreen(onNavigate = navigateRoute) } - composable(route = AppRoute.ART_PREVIEW) { - app.closer.ui.debug.ArtPreviewScreen(onNavigate = navigateRoute) - } - composable(route = AppRoute.PAIRED_HOME_PREVIEW) { - app.closer.ui.home.PairedHomePreviewScreen(onNavigate = navigateRoute) + // Dev-only art/layout previews: keep them out of the release nav graph. + if (app.closer.BuildConfig.DEBUG) { + composable(route = AppRoute.ART_PREVIEW) { + app.closer.ui.debug.ArtPreviewScreen(onNavigate = navigateRoute) + } + composable(route = AppRoute.PAIRED_HOME_PREVIEW) { + app.closer.ui.home.PairedHomePreviewScreen(onNavigate = navigateRoute) + } } } } diff --git a/app/src/main/java/app/closer/core/navigation/AppRoute.kt b/app/src/main/java/app/closer/core/navigation/AppRoute.kt index 56c72dd7..7e94dda1 100644 --- a/app/src/main/java/app/closer/core/navigation/AppRoute.kt +++ b/app/src/main/java/app/closer/core/navigation/AppRoute.kt @@ -43,7 +43,6 @@ object AppRoute { const val DELETE_ACCOUNT = "delete_account" const val SECURITY = "security_settings" const val CHANGE_PASSWORD = "change_password" - const val WHEEL_HISTORY = "wheel_history" const val GAME_HISTORY = "game_history" const val THIS_OR_THAT_REPLAY = "this_or_that_replay/{sessionId}" const val DESIRE_SYNC_REPLAY = "desire_sync_replay/{sessionId}" @@ -122,7 +121,6 @@ object AppRoute { Definition(DELETE_ACCOUNT, "Delete Account", "settings"), Definition(SECURITY, "Security", "settings"), Definition(CHANGE_PASSWORD, "Change Password", "settings"), - Definition(WHEEL_HISTORY, "Wheel History", "wheel"), Definition(GAME_HISTORY, "Past Games", "play"), Definition(THIS_OR_THAT_REPLAY, "This or That Results", "play"), Definition(DESIRE_SYNC_REPLAY, "Desire Sync Results", "play"), @@ -178,7 +176,6 @@ object AppRoute { SPIN_WHEEL_RANDOM, WHEEL_SESSION, WHEEL_COMPLETE, - WHEEL_HISTORY, GAME_HISTORY, THIS_OR_THAT_REPLAY, DESIRE_SYNC_REPLAY, diff --git a/app/src/main/java/app/closer/ui/components/BrandMessageRotator.kt b/app/src/main/java/app/closer/ui/components/BrandMessageRotator.kt index 4b0642a3..91239caf 100644 --- a/app/src/main/java/app/closer/ui/components/BrandMessageRotator.kt +++ b/app/src/main/java/app/closer/ui/components/BrandMessageRotator.kt @@ -21,6 +21,7 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import app.closer.ui.brand.CloserBrandCopy import kotlinx.coroutines.delay @@ -79,7 +80,10 @@ fun BrandMessageRotator( style = style, color = color, textAlign = TextAlign.Center, - maxLines = 3 + // The primary privacy message wraps to 4 lines at default font scale on the + // welcome/splash width; 3 clipped it mid-sentence with no ellipsis (AUTH-TRUNC-001). + maxLines = 4, + overflow = TextOverflow.Ellipsis ) } } diff --git a/app/src/main/java/app/closer/ui/dates/DateMatchScreen.kt b/app/src/main/java/app/closer/ui/dates/DateMatchScreen.kt index c2500583..9887bd62 100644 --- a/app/src/main/java/app/closer/ui/dates/DateMatchScreen.kt +++ b/app/src/main/java/app/closer/ui/dates/DateMatchScreen.kt @@ -585,7 +585,7 @@ private fun MatchOverlay( ) Text( - text = "It is a match!", + text = "It’s a match!", style = MaterialTheme.typography.headlineSmall.copy(fontWeight = FontWeight.SemiBold), color = MaterialTheme.colorScheme.onSurface ) diff --git a/app/src/main/java/app/closer/ui/home/HomeViewModel.kt b/app/src/main/java/app/closer/ui/home/HomeViewModel.kt index ec320deb..574783f7 100644 --- a/app/src/main/java/app/closer/ui/home/HomeViewModel.kt +++ b/app/src/main/java/app/closer/ui/home/HomeViewModel.kt @@ -1015,6 +1015,8 @@ class HomeViewModel @Inject constructor( private fun String.toHomeLabel(): String = split("_", "-") .filter { part -> part.isNotBlank() } + // Internal format tokens (e.g. the "mc" in daily_fun_mc) must never face users. + .filterNot { part -> part.lowercase() in setOf("mc") } .joinToString(" ") { part -> part.replaceFirstChar { it.uppercaseChar() } } companion object { diff --git a/app/src/main/java/app/closer/ui/settings/EditProfileScreen.kt b/app/src/main/java/app/closer/ui/settings/EditProfileScreen.kt index 782bff95..aae4904c 100644 --- a/app/src/main/java/app/closer/ui/settings/EditProfileScreen.kt +++ b/app/src/main/java/app/closer/ui/settings/EditProfileScreen.kt @@ -76,44 +76,8 @@ import app.closer.ui.settings.SettingsPrimaryDeep import app.closer.ui.components.CloserGlyphs @OptIn(ExperimentalMaterial3Api::class) -@Composable -fun EditProfileScreen( - onNavigate: (String) -> Unit = {}, - viewModel: EditProfileViewModel = hiltViewModel() -) { - val snackbar = remember { SnackbarHostState() } - - Scaffold( - snackbarHost = { SnackbarHost(snackbar) }, - containerColor = Color.Transparent, - modifier = Modifier.background(SettingsBackgroundBrush), - topBar = { - TopAppBar( - title = { Text("Edit profile", color = SettingsInk) }, - navigationIcon = { - IconButton(onClick = { onNavigate("back") }) { - Icon( - CloserGlyphs.Back, - contentDescription = "Back", - tint = SettingsInk - ) - } - }, - colors = TopAppBarDefaults.topAppBarColors(containerColor = Color.Transparent) - ) - } - ) { padding -> - EditProfileContent( - modifier = Modifier - .fillMaxSize() - .padding(padding) - .verticalScroll(rememberScrollState()), - snackbar = snackbar, - viewModel = viewModel - ) - } -} - +// The routed EditProfileScreen wrapper was removed as dead code (no nav route references +// it); AccountScreen embeds EditProfileContent directly. @Composable fun EditProfileContent( modifier: Modifier = Modifier, diff --git a/app/src/main/java/app/closer/ui/theme/Color.kt b/app/src/main/java/app/closer/ui/theme/Color.kt deleted file mode 100644 index 85dda39b..00000000 --- a/app/src/main/java/app/closer/ui/theme/Color.kt +++ /dev/null @@ -1,20 +0,0 @@ -package app.closer.ui.theme - -import androidx.compose.ui.graphics.Color - -// Dark theme colors (for reference if needed) -val darkPrimaryColor = Color(0xFFD7BBFF) -val darkPrimaryContainerColor = Color(0xFF4D3865) -val darkSecondaryColor = Color(0xFFE8B7D0) -val darkTertiaryColor = Color(0xFFC9C1FF) -val darkBackgroundColor = Color(0xFF111015) -val darkSurfaceColor = Color(0xFF19161F) -val darkErrorColor = Color(0xFFFFB4AB) - -val darkOnPrimaryColor = Color(0xFF37204E) -val darkOnPrimaryContainerColor = Color(0xFFF2E8FF) -val darkOnSecondaryColor = Color(0xFF482638) -val darkOnTertiaryColor = Color(0xFF302A55) -val darkOnBackgroundColor = Color(0xFFEDE7EF) -val darkOnSurfaceColor = Color(0xFFEDE7EF) -val darkOnErrorColor = Color(0xFF690005) diff --git a/app/src/main/java/app/closer/ui/wheel/CategoryPickerScreen.kt b/app/src/main/java/app/closer/ui/wheel/CategoryPickerScreen.kt index 92d4dbba..6af5627f 100644 --- a/app/src/main/java/app/closer/ui/wheel/CategoryPickerScreen.kt +++ b/app/src/main/java/app/closer/ui/wheel/CategoryPickerScreen.kt @@ -63,7 +63,7 @@ fun CategoryPickerScreen( if (item.isLocked) onNavigate(AppRoute.PAYWALL) else onNavigate(AppRoute.spinWheel(item.category.id)) }, - onHistory = { onNavigate(AppRoute.WHEEL_HISTORY) }, + onHistory = { onNavigate(AppRoute.GAME_HISTORY) }, onRetry = viewModel::load ) } diff --git a/app/src/main/java/app/closer/ui/wheel/SpinWheelViewModel.kt b/app/src/main/java/app/closer/ui/wheel/SpinWheelViewModel.kt index 0b7ee33e..86658929 100644 --- a/app/src/main/java/app/closer/ui/wheel/SpinWheelViewModel.kt +++ b/app/src/main/java/app/closer/ui/wheel/SpinWheelViewModel.kt @@ -215,7 +215,7 @@ class SpinWheelViewModel @Inject constructor( } fun onHistory() { - _uiState.update { it.copy(navigateTo = AppRoute.WHEEL_HISTORY) } + _uiState.update { it.copy(navigateTo = AppRoute.GAME_HISTORY) } } fun onNavigated() {