diff --git a/app/src/main/java/eu/darken/capod/common/settings/ProBadge.kt b/app/src/main/java/eu/darken/capod/common/settings/ProBadge.kt new file mode 100644 index 00000000..b3f83fc5 --- /dev/null +++ b/app/src/main/java/eu/darken/capod/common/settings/ProBadge.kt @@ -0,0 +1,30 @@ +package eu.darken.capod.common.settings + +import androidx.compose.foundation.layout.size +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.twotone.Stars +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import eu.darken.capod.R +import eu.darken.capod.common.compose.Preview2 +import eu.darken.capod.common.compose.PreviewWrapper + +@Composable +fun ProBadge(modifier: Modifier = Modifier) { + Icon( + imageVector = Icons.TwoTone.Stars, + contentDescription = stringResource(R.string.overview_anc_mode_requires_upgrade), + tint = MaterialTheme.colorScheme.primary, + modifier = modifier.size(16.dp), + ) +} + +@Preview2 +@Composable +private fun ProBadgePreview() = PreviewWrapper { + ProBadge() +} diff --git a/app/src/main/java/eu/darken/capod/common/settings/SettingsBaseItem.kt b/app/src/main/java/eu/darken/capod/common/settings/SettingsBaseItem.kt index 1166ca28..a1ef72be 100644 --- a/app/src/main/java/eu/darken/capod/common/settings/SettingsBaseItem.kt +++ b/app/src/main/java/eu/darken/capod/common/settings/SettingsBaseItem.kt @@ -4,9 +4,11 @@ import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text @@ -36,6 +38,7 @@ fun SettingsBaseItem( iconSize: Dp = 24.dp, subtitle: String? = null, enabled: Boolean = true, + proLocked: Boolean = false, onLongClick: (() -> Unit)? = null, trailingContent: @Composable (() -> Unit)? = null, ) { @@ -87,12 +90,18 @@ fun SettingsBaseItem( .weight(1f) .padding(start = if (hasIcon) 16.dp else 0.dp) ) { - Text( - text = title, - style = MaterialTheme.typography.bodyLarge, - fontWeight = FontWeight.Normal, - color = MaterialTheme.colorScheme.onSurface.copy(alpha = contentAlpha) - ) + Row(verticalAlignment = Alignment.CenterVertically) { + Text( + text = title, + style = MaterialTheme.typography.bodyLarge, + fontWeight = FontWeight.Normal, + color = MaterialTheme.colorScheme.onSurface.copy(alpha = contentAlpha) + ) + if (proLocked) { + Spacer(modifier = Modifier.width(6.dp)) + ProBadge() + } + } if (subtitle != null) { Text( text = subtitle, diff --git a/app/src/main/java/eu/darken/capod/common/settings/SettingsListPreferenceItem.kt b/app/src/main/java/eu/darken/capod/common/settings/SettingsListPreferenceItem.kt index f3359ecb..6aad1e42 100644 --- a/app/src/main/java/eu/darken/capod/common/settings/SettingsListPreferenceItem.kt +++ b/app/src/main/java/eu/darken/capod/common/settings/SettingsListPreferenceItem.kt @@ -38,6 +38,7 @@ fun SettingsListPreferenceItem( modifier: Modifier = Modifier, subtitle: String? = null, enabled: Boolean = true, + proLocked: Boolean = false, ) { var showDialog by remember { mutableStateOf(false) } @@ -48,6 +49,7 @@ fun SettingsListPreferenceItem( onClick = { if (enabled) showDialog = true }, modifier = modifier, enabled = enabled, + proLocked = proLocked, ) if (showDialog) { diff --git a/app/src/main/java/eu/darken/capod/common/settings/SettingsPreferenceItem.kt b/app/src/main/java/eu/darken/capod/common/settings/SettingsPreferenceItem.kt index 28f7caf1..a91e75fc 100644 --- a/app/src/main/java/eu/darken/capod/common/settings/SettingsPreferenceItem.kt +++ b/app/src/main/java/eu/darken/capod/common/settings/SettingsPreferenceItem.kt @@ -17,6 +17,7 @@ fun SettingsPreferenceItem( subtitle: String? = null, value: String? = null, enabled: Boolean = true, + proLocked: Boolean = false, ) { val contentAlpha = if (enabled) 1f else 0.5f @@ -27,6 +28,7 @@ fun SettingsPreferenceItem( modifier = modifier, subtitle = subtitle, enabled = enabled, + proLocked = proLocked, trailingContent = if (value != null) { { Text( diff --git a/app/src/main/java/eu/darken/capod/common/settings/SettingsSwitchItem.kt b/app/src/main/java/eu/darken/capod/common/settings/SettingsSwitchItem.kt index 409ea282..79cd2b33 100644 --- a/app/src/main/java/eu/darken/capod/common/settings/SettingsSwitchItem.kt +++ b/app/src/main/java/eu/darken/capod/common/settings/SettingsSwitchItem.kt @@ -20,6 +20,7 @@ fun SettingsSwitchItem( onCheckedChange: (Boolean) -> Unit, modifier: Modifier = Modifier, enabled: Boolean = true, + proLocked: Boolean = false, ) { SettingsBaseItem( icon = icon, @@ -28,6 +29,7 @@ fun SettingsSwitchItem( modifier = modifier, subtitle = subtitle, enabled = enabled, + proLocked = proLocked, trailingContent = { Switch( checked = checked, diff --git a/app/src/main/java/eu/darken/capod/main/ui/devicesettings/DeviceSettingsScreen.kt b/app/src/main/java/eu/darken/capod/main/ui/devicesettings/DeviceSettingsScreen.kt index c8abc39b..2a2be592 100644 --- a/app/src/main/java/eu/darken/capod/main/ui/devicesettings/DeviceSettingsScreen.kt +++ b/app/src/main/java/eu/darken/capod/main/ui/devicesettings/DeviceSettingsScreen.kt @@ -24,10 +24,10 @@ import androidx.compose.material.icons.twotone.Edit import androidx.compose.material.icons.twotone.GraphicEq import androidx.compose.material.icons.twotone.Headphones import androidx.compose.material.icons.twotone.Hearing +import androidx.compose.material.icons.twotone.Loop import androidx.compose.material.icons.twotone.Mic import androidx.compose.material.icons.twotone.Nightlight import androidx.compose.material.icons.twotone.Speed -import androidx.compose.material.icons.twotone.Stars import androidx.compose.material.icons.twotone.Swipe import androidx.compose.material.icons.twotone.Timer import androidx.compose.material.icons.twotone.TouchApp @@ -147,6 +147,7 @@ fun DeviceSettingsScreenHost( onDeviceNameChange = { vm.setDeviceName(it) }, onStemActionsClick = { vm.navToStemConfig() }, onForceConnect = { vm.forceConnect() }, + onUpgrade = { vm.launchUpgrade() }, ) } @@ -175,6 +176,7 @@ fun DeviceSettingsScreen( onDeviceNameChange: (String) -> Unit = {}, onStemActionsClick: () -> Unit = {}, onForceConnect: () -> Unit = {}, + onUpgrade: () -> Unit = {}, ) { val device = state.device val features = device?.model?.features @@ -272,13 +274,25 @@ fun DeviceSettingsScreen( pendingMode = device.pendingAncMode, supportedModes = ancMode.supported, onModeSelected = onAncModeChange, - cycleMask = cycleMask, + cycleMask = if (isPro) cycleMask else null, onCycleMaskChange = onListeningModeCycleChange, onAllowOffChange = onAllowOffOptionChange, enabled = enabled, ) } + if (!isPro && features.hasListeningModeCycle) { + item("noise_control_cycle_pro") { + SettingsBaseItem( + icon = Icons.TwoTone.Loop, + title = stringResource(R.string.device_settings_listening_mode_cycle_label), + subtitle = stringResource(R.string.device_settings_listening_mode_cycle_description), + onClick = onUpgrade, + proLocked = true, + ) + } + } + val convAwareness = device.conversationalAwareness if (features.hasConversationAwareness && convAwareness != null) { item("conversation_awareness") { @@ -466,6 +480,7 @@ fun DeviceSettingsScreen( subtitle = stringResource(R.string.stem_actions_nav_description), onClick = onStemActionsClick, enabled = enabled, + proLocked = !isPro, ) } } @@ -494,14 +509,14 @@ fun DeviceSettingsScreen( val sleepDet = device.sleepDetection ?: AapSetting.SleepDetection(enabled = true) item("sleep_detection") { - ProGatedSwitchItem( + SettingsSwitchItem( icon = Icons.TwoTone.Nightlight, title = stringResource(R.string.device_settings_sleep_detection_label), subtitle = stringResource(R.string.device_settings_sleep_detection_description), checked = sleepDet.enabled, onCheckedChange = onSleepDetectionChange, enabled = enabled, - isPro = isPro, + proLocked = !isPro, ) } } @@ -996,44 +1011,6 @@ private fun ConnectedDevicesList( } } -@Composable -private fun ProGatedSwitchItem( - icon: ImageVector, - title: String, - subtitle: String?, - checked: Boolean, - onCheckedChange: (Boolean) -> Unit, - enabled: Boolean, - isPro: Boolean, -) { - if (isPro) { - SettingsSwitchItem( - icon = icon, - title = title, - subtitle = subtitle, - checked = checked, - onCheckedChange = onCheckedChange, - enabled = enabled, - ) - } else { - SettingsBaseItem( - icon = icon, - title = title, - subtitle = subtitle, - onClick = { onCheckedChange(!checked) }, - enabled = enabled, - trailingContent = { - Icon( - imageVector = Icons.TwoTone.Stars, - contentDescription = null, - tint = MaterialTheme.colorScheme.primary, - modifier = Modifier.padding(start = 16.dp), - ) - }, - ) - } -} - @Composable private fun RenameDialog( currentName: String, @@ -1193,52 +1170,64 @@ private fun AapSetting.AncMode.Value.label(): String = when (this) { AapSetting.AncMode.Value.ADAPTIVE -> stringResource(R.string.device_settings_listening_mode_cycle_adaptive) } -@Preview2 -@Composable -private fun DeviceSettingsFullPreview() = PreviewWrapper { - DeviceSettingsScreen( - state = DeviceSettingsViewModel.State( - device = PodDevice( - profileId = "preview", - label = "My AirPods Pro", - ble = MockPodDataProvider.airPodsProWithKeys(), - aap = AapPodState( - connectionState = AapPodState.ConnectionState.READY, - deviceInfo = AapDeviceInfo( - name = "AirPods Pro", - modelNumber = "A2699", - manufacturer = "Apple Inc.", - serialNumber = "W5J7KV0N04", - firmwareVersion = "7A305", - ), - settings = mapOf( - AapSetting.AncMode::class to AapSetting.AncMode( - current = AapSetting.AncMode.Value.ADAPTIVE, - supported = listOf( - AapSetting.AncMode.Value.OFF, - AapSetting.AncMode.Value.ON, - AapSetting.AncMode.Value.TRANSPARENCY, - AapSetting.AncMode.Value.ADAPTIVE, - ), - ), - AapSetting.ConversationalAwareness::class to AapSetting.ConversationalAwareness(enabled = true), - AapSetting.NcWithOneAirPod::class to AapSetting.NcWithOneAirPod(enabled = true), - AapSetting.PersonalizedVolume::class to AapSetting.PersonalizedVolume(enabled = false), - AapSetting.ToneVolume::class to AapSetting.ToneVolume(level = 75), - AapSetting.AdaptiveAudioNoise::class to AapSetting.AdaptiveAudioNoise(level = 50), - AapSetting.PressSpeed::class to AapSetting.PressSpeed(value = AapSetting.PressSpeed.Value.DEFAULT), - AapSetting.PressHoldDuration::class to AapSetting.PressHoldDuration(value = AapSetting.PressHoldDuration.Value.DEFAULT), - AapSetting.VolumeSwipe::class to AapSetting.VolumeSwipe(enabled = true), - AapSetting.VolumeSwipeLength::class to AapSetting.VolumeSwipeLength(value = AapSetting.VolumeSwipeLength.Value.DEFAULT), - AapSetting.EndCallMuteMic::class to AapSetting.EndCallMuteMic( - muteMic = AapSetting.EndCallMuteMic.MuteMicMode.DOUBLE_PRESS, - endCall = AapSetting.EndCallMuteMic.EndCallMode.SINGLE_PRESS, - ), +private fun previewFullState(isPro: Boolean) = DeviceSettingsViewModel.State( + device = PodDevice( + profileId = "preview", + label = "My AirPods Pro", + ble = MockPodDataProvider.airPodsProWithKeys(), + aap = AapPodState( + connectionState = AapPodState.ConnectionState.READY, + deviceInfo = AapDeviceInfo( + name = "AirPods Pro", + modelNumber = "A2699", + manufacturer = "Apple Inc.", + serialNumber = "W5J7KV0N04", + firmwareVersion = "7A305", + ), + settings = mapOf( + AapSetting.AncMode::class to AapSetting.AncMode( + current = AapSetting.AncMode.Value.ADAPTIVE, + supported = listOf( + AapSetting.AncMode.Value.OFF, + AapSetting.AncMode.Value.ON, + AapSetting.AncMode.Value.TRANSPARENCY, + AapSetting.AncMode.Value.ADAPTIVE, ), ), + AapSetting.ConversationalAwareness::class to AapSetting.ConversationalAwareness(enabled = true), + AapSetting.NcWithOneAirPod::class to AapSetting.NcWithOneAirPod(enabled = true), + AapSetting.PersonalizedVolume::class to AapSetting.PersonalizedVolume(enabled = false), + AapSetting.ToneVolume::class to AapSetting.ToneVolume(level = 75), + AapSetting.AdaptiveAudioNoise::class to AapSetting.AdaptiveAudioNoise(level = 50), + AapSetting.PressSpeed::class to AapSetting.PressSpeed(value = AapSetting.PressSpeed.Value.DEFAULT), + AapSetting.PressHoldDuration::class to AapSetting.PressHoldDuration(value = AapSetting.PressHoldDuration.Value.DEFAULT), + AapSetting.VolumeSwipe::class to AapSetting.VolumeSwipe(enabled = true), + AapSetting.VolumeSwipeLength::class to AapSetting.VolumeSwipeLength(value = AapSetting.VolumeSwipeLength.Value.DEFAULT), + AapSetting.EndCallMuteMic::class to AapSetting.EndCallMuteMic( + muteMic = AapSetting.EndCallMuteMic.MuteMicMode.DOUBLE_PRESS, + endCall = AapSetting.EndCallMuteMic.EndCallMode.SINGLE_PRESS, + ), ), - now = MOCK_NOW, ), + ), + now = MOCK_NOW, + isPro = isPro, +) + +@Preview2 +@Composable +private fun DeviceSettingsFullProPreview() = PreviewWrapper { + DeviceSettingsScreen( + state = previewFullState(isPro = true), + onNavigateUp = {}, + ) +} + +@Preview2 +@Composable +private fun DeviceSettingsFullNonProPreview() = PreviewWrapper { + DeviceSettingsScreen( + state = previewFullState(isPro = false), onNavigateUp = {}, ) } diff --git a/app/src/main/java/eu/darken/capod/main/ui/devicesettings/DeviceSettingsViewModel.kt b/app/src/main/java/eu/darken/capod/main/ui/devicesettings/DeviceSettingsViewModel.kt index f708cc50..eafb4171 100644 --- a/app/src/main/java/eu/darken/capod/main/ui/devicesettings/DeviceSettingsViewModel.kt +++ b/app/src/main/java/eu/darken/capod/main/ui/devicesettings/DeviceSettingsViewModel.kt @@ -220,6 +220,10 @@ class DeviceSettingsViewModel @Inject constructor( } } + fun launchUpgrade() { + navTo(Nav.Main.Upgrade) + } + companion object { private val TAG = logTag("DeviceSettings", "VM") } diff --git a/app/src/main/java/eu/darken/capod/main/ui/settings/general/GeneralSettingsScreen.kt b/app/src/main/java/eu/darken/capod/main/ui/settings/general/GeneralSettingsScreen.kt index d6fb0e77..12086cad 100644 --- a/app/src/main/java/eu/darken/capod/main/ui/settings/general/GeneralSettingsScreen.kt +++ b/app/src/main/java/eu/darken/capod/main/ui/settings/general/GeneralSettingsScreen.kt @@ -3,7 +3,6 @@ package eu.darken.capod.main.ui.settings.general import android.os.Build import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn @@ -148,43 +147,47 @@ fun GeneralSettingsScreen( ) } item { - Row(verticalAlignment = Alignment.CenterVertically) { - SettingsCategoryHeader(text = stringResource(R.string.settings_category_appearance_label)) - if (!state.isPro) { - Spacer(modifier = Modifier.weight(1f)) - TextButton( - onClick = onUpgrade, - modifier = Modifier.padding(end = 4.dp), - ) { - Text( - text = stringResource(R.string.common_feature_requires_pro_msg), - style = MaterialTheme.typography.labelSmall, - ) - } - } + SettingsCategoryHeader(text = stringResource(R.string.settings_category_appearance_label)) + } + item { + if (state.isPro) { + SettingsListPreferenceItem( + icon = Icons.TwoTone.DarkMode, + title = stringResource(R.string.ui_theme_mode_label), + entries = ThemeMode.entries, + selectedEntry = state.themeState.mode, + onEntrySelected = onThemeModeSelected, + entryLabel = { stringResource(it.labelRes) }, + ) + } else { + SettingsBaseItem( + icon = Icons.TwoTone.DarkMode, + title = stringResource(R.string.ui_theme_mode_label), + subtitle = stringResource(state.themeState.mode.labelRes), + onClick = onUpgrade, + proLocked = true, + ) } } item { - SettingsListPreferenceItem( - icon = Icons.TwoTone.DarkMode, - title = stringResource(R.string.ui_theme_mode_label), - entries = ThemeMode.entries, - selectedEntry = state.themeState.mode, - onEntrySelected = onThemeModeSelected, - entryLabel = { stringResource(it.labelRes) }, - enabled = state.isPro, - ) - } - item { - SettingsListPreferenceItem( - icon = Icons.TwoTone.Contrast, - title = stringResource(R.string.ui_theme_style_label), - entries = ThemeStyle.entries, - selectedEntry = state.themeState.style, - onEntrySelected = onThemeStyleSelected, - entryLabel = { stringResource(it.labelRes) }, - enabled = state.isPro, - ) + if (state.isPro) { + SettingsListPreferenceItem( + icon = Icons.TwoTone.Contrast, + title = stringResource(R.string.ui_theme_style_label), + entries = ThemeStyle.entries, + selectedEntry = state.themeState.style, + onEntrySelected = onThemeStyleSelected, + entryLabel = { stringResource(it.labelRes) }, + ) + } else { + SettingsBaseItem( + icon = Icons.TwoTone.Contrast, + title = stringResource(R.string.ui_theme_style_label), + subtitle = stringResource(state.themeState.style.labelRes), + onClick = onUpgrade, + proLocked = true, + ) + } } item { SettingsBaseItem( @@ -195,8 +198,11 @@ fun GeneralSettingsScreen( stringResource(state.themeState.color.labelRes) }, icon = Icons.TwoTone.Palette, - onClick = { showColorDialog = true }, - enabled = state.isPro && !isMaterialYouActive, + onClick = { + if (!state.isPro) onUpgrade() else showColorDialog = true + }, + enabled = !isMaterialYouActive, + proLocked = !state.isPro && !isMaterialYouActive, ) } item { @@ -333,21 +339,40 @@ fun GeneralSettingsScreen( } } +private fun previewGeneralState(isPro: Boolean) = GeneralSettingsViewModel.State( + isPro = isPro, + monitorMode = MonitorMode.AUTOMATIC, + scannerMode = ScannerMode.BALANCED, + showConnectedNotification = true, + keepNotificationAfterDisconnect = false, + isOffloadedFilteringDisabled = false, + isOffloadedBatchingDisabled = false, + useIndirectScanResultCallback = false, + themeState = ThemeState(), +) + @Preview2 @Composable -private fun GeneralSettingsScreenPreview() = PreviewWrapper { +private fun GeneralSettingsScreenProPreview() = PreviewWrapper { GeneralSettingsScreen( - state = GeneralSettingsViewModel.State( - isPro = true, - monitorMode = MonitorMode.AUTOMATIC, - scannerMode = ScannerMode.BALANCED, - showConnectedNotification = true, - keepNotificationAfterDisconnect = false, - isOffloadedFilteringDisabled = false, - isOffloadedBatchingDisabled = false, - useIndirectScanResultCallback = false, - themeState = ThemeState(), - ), + state = previewGeneralState(isPro = true), + onNavigateUp = {}, + onMonitorModeSelected = {}, + onScannerModeSelected = {}, + onShowConnectedNotificationChanged = {}, + onKeepNotificationAfterDisconnectChanged = {}, + onDebugSettings = {}, + onOffloadedFilteringDisabledChanged = {}, + onOffloadedBatchingDisabledChanged = {}, + onUseIndirectScanResultCallbackChanged = {}, + ) +} + +@Preview2 +@Composable +private fun GeneralSettingsScreenNonProPreview() = PreviewWrapper { + GeneralSettingsScreen( + state = previewGeneralState(isPro = false), onNavigateUp = {}, onMonitorModeSelected = {}, onScannerModeSelected = {}, diff --git a/app/src/main/java/eu/darken/capod/reaction/ui/ReactionSettingsScreen.kt b/app/src/main/java/eu/darken/capod/reaction/ui/ReactionSettingsScreen.kt index 4b095863..541b02b8 100644 --- a/app/src/main/java/eu/darken/capod/reaction/ui/ReactionSettingsScreen.kt +++ b/app/src/main/java/eu/darken/capod/reaction/ui/ReactionSettingsScreen.kt @@ -15,8 +15,6 @@ import androidx.compose.material.icons.automirrored.twotone.Message import androidx.compose.material.icons.twotone.PauseCircle import androidx.compose.material.icons.twotone.PlayCircle import androidx.compose.material.icons.twotone.QuestionMark -import androidx.compose.material.icons.twotone.Stars -import androidx.compose.foundation.layout.size import androidx.compose.material.icons.twotone.Workspaces import androidx.compose.material3.AlertDialog import androidx.compose.material3.Icon @@ -47,6 +45,7 @@ import eu.darken.capod.common.error.ErrorEventHandler import eu.darken.capod.common.navigation.NavigationEventHandler import eu.darken.capod.common.settings.SettingsBaseItem import eu.darken.capod.common.settings.SettingsCategoryHeader +import eu.darken.capod.common.settings.SettingsSwitchItem import eu.darken.capod.reaction.core.autoconnect.AutoConnectCondition @Composable @@ -122,25 +121,23 @@ fun ReactionSettingsScreen( ) } item { - SettingsBaseItem( + SettingsSwitchItem( + icon = Icons.TwoTone.PlayCircle, title = stringResource(R.string.settings_autopplay_label), subtitle = stringResource(R.string.settings_autoplay_description), - icon = Icons.TwoTone.PlayCircle, - onClick = { onAutoPlayChanged(!state.autoPlay) }, - trailingContent = { - ProGatedToggle(isPro = state.isPro, checked = state.autoPlay, onCheckedChange = onAutoPlayChanged) - }, + checked = state.autoPlay, + onCheckedChange = onAutoPlayChanged, + proLocked = !state.isPro, ) } item { - SettingsBaseItem( + SettingsSwitchItem( + icon = Icons.TwoTone.PauseCircle, title = stringResource(R.string.settings_autopause_label), subtitle = stringResource(R.string.settings_autopause_description), - icon = Icons.TwoTone.PauseCircle, - onClick = { onAutoPauseChanged(!state.autoPause) }, - trailingContent = { - ProGatedToggle(isPro = state.isPro, checked = state.autoPause, onCheckedChange = onAutoPauseChanged) - }, + checked = state.autoPause, + onCheckedChange = onAutoPauseChanged, + proLocked = !state.isPro, ) } item { @@ -156,14 +153,13 @@ fun ReactionSettingsScreen( SettingsCategoryHeader(text = stringResource(R.string.settings_autoconnect_label)) } item { - SettingsBaseItem( + SettingsSwitchItem( + icon = Icons.TwoTone.BluetoothConnected, title = stringResource(R.string.settings_autoconnect_label), subtitle = stringResource(R.string.settings_autoconnect_description), - icon = Icons.TwoTone.BluetoothConnected, - onClick = { onAutoConnectChanged(!state.autoConnect) }, - trailingContent = { - ProGatedToggle(isPro = state.isPro, checked = state.autoConnect, onCheckedChange = onAutoConnectChanged) - }, + checked = state.autoConnect, + onCheckedChange = onAutoConnectChanged, + proLocked = !state.isPro, ) } item { @@ -179,25 +175,23 @@ fun ReactionSettingsScreen( SettingsCategoryHeader(text = stringResource(R.string.settings_category_other_label)) } item { - SettingsBaseItem( + SettingsSwitchItem( + icon = Icons.AutoMirrored.TwoTone.Message, title = stringResource(R.string.settings_popup_caseopen_label), subtitle = stringResource(R.string.settings_popup_caseopen_description), - icon = Icons.AutoMirrored.TwoTone.Message, - onClick = { onShowPopUpOnCaseOpenChanged(!state.showPopUpOnCaseOpen) }, - trailingContent = { - ProGatedToggle(isPro = state.isPro, checked = state.showPopUpOnCaseOpen, onCheckedChange = onShowPopUpOnCaseOpenChanged) - }, + checked = state.showPopUpOnCaseOpen, + onCheckedChange = onShowPopUpOnCaseOpenChanged, + proLocked = !state.isPro, ) } item { - SettingsBaseItem( + SettingsSwitchItem( + icon = Icons.AutoMirrored.TwoTone.Message, title = stringResource(R.string.settings_popup_connected_label), subtitle = stringResource(R.string.settings_popup_connected_description), - icon = Icons.AutoMirrored.TwoTone.Message, - onClick = { onShowPopUpOnConnectionChanged(!state.showPopUpOnConnection) }, - trailingContent = { - ProGatedToggle(isPro = state.isPro, checked = state.showPopUpOnConnection, onCheckedChange = onShowPopUpOnConnectionChanged) - }, + checked = state.showPopUpOnConnection, + onCheckedChange = onShowPopUpOnConnectionChanged, + proLocked = !state.isPro, ) } } @@ -247,28 +241,6 @@ fun ReactionSettingsScreen( } } -@Composable -private fun ProGatedToggle( - isPro: Boolean, - checked: Boolean, - onCheckedChange: (Boolean) -> Unit, -) { - if (isPro) { - Switch( - checked = checked, - onCheckedChange = onCheckedChange, - modifier = Modifier.padding(start = 16.dp), - ) - } else { - Icon( - imageVector = Icons.TwoTone.Stars, - contentDescription = null, - tint = MaterialTheme.colorScheme.primary, - modifier = Modifier.padding(start = 16.dp).size(24.dp), - ) - } -} - @Preview2 @Composable private fun ReactionSettingsScreenPreview() = PreviewWrapper { @@ -293,3 +265,28 @@ private fun ReactionSettingsScreenPreview() = PreviewWrapper { onShowPopUpOnConnectionChanged = {}, ) } + +@Preview2 +@Composable +private fun ReactionSettingsScreenNonProPreview() = PreviewWrapper { + ReactionSettingsScreen( + state = ReactionSettingsViewModel.State( + isPro = false, + onePodMode = false, + autoPlay = false, + autoPause = false, + autoConnect = false, + autoConnectCondition = AutoConnectCondition.WHEN_SEEN, + showPopUpOnCaseOpen = false, + showPopUpOnConnection = false, + ), + onNavigateUp = {}, + onOnePodModeChanged = {}, + onAutoPlayChanged = {}, + onAutoPauseChanged = {}, + onAutoConnectChanged = {}, + onAutoConnectConditionSelected = {}, + onShowPopUpOnCaseOpenChanged = {}, + onShowPopUpOnConnectionChanged = {}, + ) +}