mirror of
				https://github.com/SimpleMobileTools/Simple-Calculator.git
				synced 2025-06-05 21:49:13 +02:00 
			
		
		
		
	fully implement the compose theming and hook up the settings logic
This commit is contained in:
		| @@ -101,10 +101,10 @@ dependencies { | |||||||
|     implementation(libs.simple.tools.commons) |     implementation(libs.simple.tools.commons) | ||||||
|     implementation(libs.auto.fit.text.view) |     implementation(libs.auto.fit.text.view) | ||||||
|     implementation(libs.exp4j) |     implementation(libs.exp4j) | ||||||
|  |     implementation(libs.bundles.lifecycle) | ||||||
|     implementation(libs.bundles.compose) |     implementation(libs.bundles.compose) | ||||||
|     implementation(libs.bundles.accompanist) |     implementation(libs.bundles.accompanist) | ||||||
|     implementation(libs.bundles.compose.preview) |     debugImplementation(libs.bundles.compose.preview) | ||||||
|  |  | ||||||
|     implementation(libs.bundles.room) |     implementation(libs.bundles.room) | ||||||
|     ksp(libs.androidx.room.compiler) |     ksp(libs.androidx.room.compiler) | ||||||
|   | |||||||
| @@ -1,119 +1,95 @@ | |||||||
| package com.simplemobiletools.calculator.activities | package com.simplemobiletools.calculator.activities | ||||||
|  |  | ||||||
| import android.app.ActivityManager | import android.annotation.SuppressLint | ||||||
| import android.content.Intent | import android.content.Intent | ||||||
| import android.os.Build |  | ||||||
| import android.os.Bundle | import android.os.Bundle | ||||||
| import android.view.View |  | ||||||
| import androidx.activity.compose.setContent | import androidx.activity.compose.setContent | ||||||
| import androidx.appcompat.app.AppCompatActivity | import androidx.appcompat.app.AppCompatActivity | ||||||
|  | import androidx.compose.runtime.* | ||||||
|  | import androidx.compose.ui.platform.LocalContext | ||||||
|  | import androidx.lifecycle.compose.collectAsStateWithLifecycle | ||||||
| import com.simplemobiletools.calculator.compose.screens.SettingsScreen | import com.simplemobiletools.calculator.compose.screens.SettingsScreen | ||||||
| import com.simplemobiletools.calculator.compose.theme.AppThemeSurface | import com.simplemobiletools.calculator.compose.theme.AppThemeSurface | ||||||
| import com.simplemobiletools.calculator.databinding.ActivitySettingsBinding | import com.simplemobiletools.calculator.compose.theme.OnLifecycleEvent | ||||||
| import com.simplemobiletools.calculator.extensions.calculatorDB | import com.simplemobiletools.calculator.compose.theme.getAppIconIds | ||||||
| import com.simplemobiletools.calculator.extensions.config | import com.simplemobiletools.calculator.compose.theme.getAppLauncherName | ||||||
| import com.simplemobiletools.calculator.extensions.updateWidgets | import com.simplemobiletools.calculator.extensions.* | ||||||
| import com.simplemobiletools.calculator.extensions.viewBinding |  | ||||||
| import com.simplemobiletools.commons.activities.CustomizationActivity | import com.simplemobiletools.commons.activities.CustomizationActivity | ||||||
| import com.simplemobiletools.commons.extensions.* | import com.simplemobiletools.commons.extensions.isOrWasThankYouInstalled | ||||||
|  | import com.simplemobiletools.commons.extensions.launchPurchaseThankYouIntent | ||||||
| import com.simplemobiletools.commons.helpers.* | import com.simplemobiletools.commons.helpers.* | ||||||
| import java.util.Locale | import java.util.Locale | ||||||
| import kotlin.system.exitProcess | import kotlin.system.exitProcess | ||||||
|  |  | ||||||
| class SettingsActivity : AppCompatActivity() { | class SettingsActivity : AppCompatActivity() { | ||||||
|  |  | ||||||
|     private val binding by viewBinding(ActivitySettingsBinding::inflate) |  | ||||||
|     private val preferences by lazy { config } |     private val preferences by lazy { config } | ||||||
|  |  | ||||||
|  |     @SuppressLint("NewApi") | ||||||
|     override fun onCreate(savedInstanceState: Bundle?) { |     override fun onCreate(savedInstanceState: Bundle?) { | ||||||
|         super.onCreate(savedInstanceState) |         super.onCreate(savedInstanceState) | ||||||
|         setContent { |         setContent { | ||||||
|             AppThemeSurface { |             AppThemeSurface { | ||||||
|  |                 val context = LocalContext.current | ||||||
|  |                 val preventPhoneFromSleeping by preferences.preventPhoneFromSleepingFlow.collectAsStateWithLifecycle(preferences.preventPhoneFromSleeping) | ||||||
|  |                 val vibrateOnButtonPressFlow by preferences.vibrateOnButtonPressFlow.collectAsStateWithLifecycle(preferences.vibrateOnButtonPress) | ||||||
|  |                 val wasUseEnglishToggledFlow by preferences.wasUseEnglishToggledFlow.collectAsStateWithLifecycle(preferences.wasUseEnglishToggled) | ||||||
|  |                 val useEnglishFlow by preferences.useEnglishFlow.collectAsStateWithLifecycle(preferences.useEnglish) | ||||||
|  |                 val useCommaAsDecimalMarkFlow by preferences.useCommaAsDecimalMarkFlow.collectAsStateWithLifecycle(preferences.useCommaAsDecimalMark) | ||||||
|  |                 val isUseEnglishEnabled by remember(wasUseEnglishToggledFlow) { | ||||||
|  |                     derivedStateOf { | ||||||
|  |                         (wasUseEnglishToggledFlow || Locale.getDefault().language != "en") && !isTiramisuPlus() | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 var isOrWasThankYouInstalled by remember { mutableStateOf(false) } | ||||||
|  |  | ||||||
|  |                 OnLifecycleEvent { event -> | ||||||
|  |                     if (event == androidx.lifecycle.Lifecycle.Event.ON_RESUME) { | ||||||
|  |                         isOrWasThankYouInstalled = context.isOrWasThankYouInstalled() | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|                 SettingsScreen( |                 SettingsScreen( | ||||||
|                     customizeColors = ::handleCustomizeColorsClick, goBack = ::finish |                     preventPhoneFromSleeping = preventPhoneFromSleeping, | ||||||
|  |                     customizeColors = ::handleCustomizeColorsClick, | ||||||
|  |                     goBack = ::finish, | ||||||
|  |                     customizeWidgetColors = ::setupCustomizeWidgetColors, | ||||||
|  |                     onPreventPhoneFromSleeping = preferences::preventPhoneFromSleeping::set, | ||||||
|  |                     vibrateOnButtonPressFlow = vibrateOnButtonPressFlow, | ||||||
|  |                     onVibrateOnButtonPressFlow = preferences::vibrateOnButtonPress::set, | ||||||
|  |                     isOrWasThankYouInstalled = isOrWasThankYouInstalled, | ||||||
|  |                     onThankYou = ::launchPurchaseThankYouIntent, | ||||||
|  |                     isUseEnglishEnabled = isUseEnglishEnabled, | ||||||
|  |                     isUseEnglishChecked = useEnglishFlow, | ||||||
|  |                     onUseEnglishPress = { isChecked -> | ||||||
|  |                         preferences.useEnglish = isChecked | ||||||
|  |                         exitProcess(0) | ||||||
|  |                     }, | ||||||
|  |                     onSetupLanguagePress = ::launchChangeAppLanguageIntent, | ||||||
|  |                     useCommaAsDecimalMarkFlow = useCommaAsDecimalMarkFlow, | ||||||
|  |                     onUseCommaAsDecimalMarkFlow = { isChecked -> | ||||||
|  |                         preferences.useCommaAsDecimalMark = isChecked | ||||||
|  |                         updateWidgets() | ||||||
|  |                         ensureBackgroundThread { | ||||||
|  |                             applicationContext.calculatorDB.deleteHistory() | ||||||
|  |                         } | ||||||
|  |                     }, | ||||||
|                 ) |                 ) | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     private fun setupPurchaseThankYou() { |  | ||||||
|         binding.settingsPurchaseThankYouHolder.beGoneIf(isOrWasThankYouInstalled()) |  | ||||||
|         binding.settingsPurchaseThankYouHolder.setOnClickListener { |  | ||||||
|             launchPurchaseThankYouIntent() |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private fun setupCustomizeColors() { |  | ||||||
|         binding.settingsWidgetColorCustomizationLabel.text = getCustomizeColorsString() |  | ||||||
|         binding.settingsWidgetColorCustomizationHolder.setOnClickListener { |  | ||||||
|             handleCustomizeColorsClick() |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private fun handleCustomizeColorsClick() { |     private fun handleCustomizeColorsClick() { | ||||||
|         Intent(applicationContext, CustomizationActivity::class.java).apply { |         Intent(applicationContext, CustomizationActivity::class.java).apply { | ||||||
|             /*putExtra(APP_ICON_IDS, getAppIconIDs()) |             putExtra(APP_ICON_IDS, getAppIconIds()) | ||||||
|             putExtra(APP_LAUNCHER_NAME, getAppLauncherName())*/ |             putExtra(APP_LAUNCHER_NAME, getAppLauncherName()) | ||||||
|             startActivity(this) |             startActivity(this) | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private fun setupUseEnglish() { |  | ||||||
|         binding.settingsUseEnglishHolder.beVisibleIf((preferences.wasUseEnglishToggled || Locale.getDefault().language != "en") && !isTiramisuPlus()) |  | ||||||
|         binding.settingsUseEnglish.isChecked = preferences.useEnglish |  | ||||||
|         binding.settingsUseEnglishHolder.setOnClickListener { |  | ||||||
|             binding.settingsUseEnglish.toggle() |  | ||||||
|             preferences.useEnglish = binding.settingsUseEnglish.isChecked |  | ||||||
|             exitProcess(0) |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private fun setupLanguage() { |  | ||||||
|         binding.settingsLanguage.text = Locale.getDefault().displayLanguage |  | ||||||
|         binding.settingsLanguageHolder.beVisibleIf(isTiramisuPlus()) |  | ||||||
|         binding.settingsLanguageHolder.setOnClickListener { |  | ||||||
|             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { |  | ||||||
|                 // launchChangeAppLanguageIntent() |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private fun setupVibrate() { |  | ||||||
|         binding.settingsVibrate.isChecked = preferences.vibrateOnButtonPress |  | ||||||
|         binding.settingsVibrateHolder.setOnClickListener { |  | ||||||
|             binding.settingsVibrate.toggle() |  | ||||||
|             preferences.vibrateOnButtonPress = binding.settingsVibrate.isChecked |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private fun setupPreventPhoneFromSleeping() { |  | ||||||
|         binding.settingsPreventPhoneFromSleeping.isChecked = preferences.preventPhoneFromSleeping |  | ||||||
|         binding.settingsPreventPhoneFromSleepingHolder.setOnClickListener { |  | ||||||
|             binding.settingsPreventPhoneFromSleeping.toggle() |  | ||||||
|             preferences.preventPhoneFromSleeping = binding.settingsPreventPhoneFromSleeping.isChecked |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private fun setupUseCommaAsDecimalMark() { |  | ||||||
|         binding.settingsUseCommaAsDecimalMark.isChecked = preferences.useCommaAsDecimalMark |  | ||||||
|         binding.settingsUseCommaAsDecimalMark.setOnClickListener { |  | ||||||
|             binding.settingsUseCommaAsDecimalMark.toggle() |  | ||||||
|             preferences.useCommaAsDecimalMark = binding.settingsUseCommaAsDecimalMark.isChecked |  | ||||||
|             updateWidgets() |  | ||||||
|             ensureBackgroundThread { |  | ||||||
|                 applicationContext.calculatorDB.deleteHistory() |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private fun setupCustomizeWidgetColors() { |     private fun setupCustomizeWidgetColors() { | ||||||
|         binding.settingsWidgetColorCustomizationHolder.setOnClickListener { |  | ||||||
|         Intent(this, WidgetConfigureActivity::class.java).apply { |         Intent(this, WidgetConfigureActivity::class.java).apply { | ||||||
|             putExtra(IS_CUSTOMIZING_COLORS, true) |             putExtra(IS_CUSTOMIZING_COLORS, true) | ||||||
|             startActivity(this) |             startActivity(this) | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| } |  | ||||||
|   | |||||||
| @@ -1,6 +1,5 @@ | |||||||
| package com.simplemobiletools.calculator.compose.screens | package com.simplemobiletools.calculator.compose.screens | ||||||
|  |  | ||||||
| import androidx.compose.foundation.background |  | ||||||
| import androidx.compose.foundation.clickable | import androidx.compose.foundation.clickable | ||||||
| import androidx.compose.foundation.layout.* | import androidx.compose.foundation.layout.* | ||||||
| import androidx.compose.foundation.rememberScrollState | import androidx.compose.foundation.rememberScrollState | ||||||
| @@ -9,10 +8,12 @@ import androidx.compose.material.icons.Icons | |||||||
| import androidx.compose.material.icons.filled.ArrowBack | import androidx.compose.material.icons.filled.ArrowBack | ||||||
| import androidx.compose.material3.* | import androidx.compose.material3.* | ||||||
| import androidx.compose.runtime.Composable | import androidx.compose.runtime.Composable | ||||||
|  | import androidx.compose.runtime.remember | ||||||
| import androidx.compose.ui.Modifier | import androidx.compose.ui.Modifier | ||||||
| import androidx.compose.ui.graphics.Color | import androidx.compose.ui.graphics.Color | ||||||
| import androidx.compose.ui.graphics.toArgb | import androidx.compose.ui.graphics.lerp | ||||||
| import androidx.compose.ui.input.nestedscroll.nestedScroll | import androidx.compose.ui.input.nestedscroll.nestedScroll | ||||||
|  | import androidx.compose.ui.platform.LocalContext | ||||||
| import androidx.compose.ui.res.stringResource | import androidx.compose.ui.res.stringResource | ||||||
| import androidx.compose.ui.unit.dp | import androidx.compose.ui.unit.dp | ||||||
| import com.simplemobiletools.calculator.compose.extensions.MyDevices | import com.simplemobiletools.calculator.compose.extensions.MyDevices | ||||||
| @@ -21,15 +22,45 @@ import com.simplemobiletools.calculator.compose.settings.SettingsGroup | |||||||
| import com.simplemobiletools.calculator.compose.settings.SettingsPreferenceComponent | import com.simplemobiletools.calculator.compose.settings.SettingsPreferenceComponent | ||||||
| import com.simplemobiletools.calculator.compose.settings.SettingsTitleTextComponent | import com.simplemobiletools.calculator.compose.settings.SettingsTitleTextComponent | ||||||
| import com.simplemobiletools.calculator.compose.theme.AppThemeSurface | import com.simplemobiletools.calculator.compose.theme.AppThemeSurface | ||||||
|  | import com.simplemobiletools.calculator.compose.theme.isSurfaceLitWell | ||||||
| import com.simplemobiletools.commons.R | import com.simplemobiletools.commons.R | ||||||
|  | import com.simplemobiletools.commons.extensions.getCustomizeColorsString | ||||||
|  | import com.simplemobiletools.commons.helpers.isTiramisuPlus | ||||||
|  | import java.util.Locale | ||||||
|  | import kotlin.reflect.KFunction1 | ||||||
|  |  | ||||||
| @Composable | @Composable | ||||||
| fun SettingsScreen( | fun SettingsScreen( | ||||||
|     goBack: () -> Unit, |     goBack: () -> Unit, | ||||||
|     customizeColors: () -> Unit, |     customizeColors: () -> Unit, | ||||||
|     topBarsScrolledContainerColor: Color = MaterialTheme.colorScheme.primary |     customizeWidgetColors: () -> Unit, | ||||||
|  |     topBarsScrolledContainerColor: Color = MaterialTheme.colorScheme.primary, | ||||||
|  |     nonScrolledTextColor: Color = if (isSurfaceLitWell()) Color.Black else Color.White, | ||||||
|  |     scrolledTextColor: Color = Color.White, | ||||||
|  |     preventPhoneFromSleeping: Boolean, | ||||||
|  |     onPreventPhoneFromSleeping: (Boolean) -> Unit, | ||||||
|  |     vibrateOnButtonPressFlow: Boolean, | ||||||
|  |     onVibrateOnButtonPressFlow: (Boolean) -> Unit, | ||||||
|  |     isOrWasThankYouInstalled: Boolean, | ||||||
|  |     onThankYou: () -> Unit, | ||||||
|  |     isUseEnglishEnabled: Boolean, | ||||||
|  |     isUseEnglishChecked: Boolean, | ||||||
|  |     onUseEnglishPress: (Boolean) -> Unit, | ||||||
|  |     onSetupLanguagePress: () -> Unit, | ||||||
|  |     useCommaAsDecimalMarkFlow: Boolean, | ||||||
|  |     onUseCommaAsDecimalMarkFlow: (Boolean) -> Unit, | ||||||
| ) { | ) { | ||||||
|  |     val context = LocalContext.current | ||||||
|  |     val lockedCustomizeColorText =  if (isOrWasThankYouInstalled) null else context.getCustomizeColorsString() | ||||||
|  |     val displayLanguage = remember { Locale.getDefault().displayLanguage } | ||||||
|     val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState()) |     val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState()) | ||||||
|  |     val colorTransitionFraction = scrollBehavior.state.overlappedFraction | ||||||
|  |     val fraction = if (colorTransitionFraction > 0.01f) 1f else 0f | ||||||
|  |     val scrolledColor = lerp( | ||||||
|  |         nonScrolledTextColor, | ||||||
|  |         scrolledTextColor, | ||||||
|  |         fraction | ||||||
|  |     ) | ||||||
|     Scaffold( |     Scaffold( | ||||||
|         modifier = Modifier |         modifier = Modifier | ||||||
|             .fillMaxSize() |             .fillMaxSize() | ||||||
| @@ -41,7 +72,8 @@ fun SettingsScreen( | |||||||
|                         text = stringResource(id = R.string.settings), |                         text = stringResource(id = R.string.settings), | ||||||
|                         modifier = Modifier |                         modifier = Modifier | ||||||
|                             .padding(start = 16.dp) |                             .padding(start = 16.dp) | ||||||
|                             .fillMaxWidth() |                             .fillMaxWidth(), | ||||||
|  |                         color = scrolledColor | ||||||
|                     ) |                     ) | ||||||
|                 }, |                 }, | ||||||
|                 navigationIcon = { |                 navigationIcon = { | ||||||
| @@ -49,12 +81,13 @@ fun SettingsScreen( | |||||||
|                         imageVector = Icons.Filled.ArrowBack, contentDescription = stringResource(id = R.string.back), |                         imageVector = Icons.Filled.ArrowBack, contentDescription = stringResource(id = R.string.back), | ||||||
|                         modifier = Modifier |                         modifier = Modifier | ||||||
|                             .clickable { goBack() } |                             .clickable { goBack() } | ||||||
|                             .padding(start = 8.dp) |                             .padding(start = 8.dp), | ||||||
|  |                         tint = scrolledColor | ||||||
|                     ) |                     ) | ||||||
|                 }, |                 }, | ||||||
|                 scrollBehavior = scrollBehavior, |                 scrollBehavior = scrollBehavior, | ||||||
|                 colors = TopAppBarDefaults.largeTopAppBarColors( |                 colors = TopAppBarDefaults.largeTopAppBarColors( | ||||||
|                     scrolledContainerColor = topBarsScrolledContainerColor, |                     scrolledContainerColor = topBarsScrolledContainerColor | ||||||
|                 ), |                 ), | ||||||
|             ) |             ) | ||||||
|         } |         } | ||||||
| @@ -67,20 +100,54 @@ fun SettingsScreen( | |||||||
|             SettingsGroup(title = { |             SettingsGroup(title = { | ||||||
|                 SettingsTitleTextComponent(text = stringResource(id = R.string.color_customization)) |                 SettingsTitleTextComponent(text = stringResource(id = R.string.color_customization)) | ||||||
|             }) { |             }) { | ||||||
|                 SettingsPreferenceComponent(preferenceTitle = stringResource(id = R.string.customize_colors), doOnPreferenceClick = customizeColors) |                 SettingsPreferenceComponent( | ||||||
|                 SettingsPreferenceComponent(preferenceTitle = stringResource(id = R.string.customize_widget_colors)) |                     preferenceTitle = stringResource(id = R.string.customize_colors), | ||||||
|  |                     doOnPreferenceClick = customizeColors, | ||||||
|  |                     isPreferenceEnabled = isOrWasThankYouInstalled, | ||||||
|  |                     preferenceSummary = lockedCustomizeColorText | ||||||
|  |                 ) | ||||||
|  |                 SettingsPreferenceComponent( | ||||||
|  |                     preferenceTitle = stringResource(id = R.string.customize_widget_colors), | ||||||
|  |                     doOnPreferenceClick = customizeWidgetColors | ||||||
|  |                 ) | ||||||
|                 Spacer(modifier = Modifier.padding(bottom = 16.dp)) |                 Spacer(modifier = Modifier.padding(bottom = 16.dp)) | ||||||
|             } |             } | ||||||
|             Divider() |             Divider() | ||||||
|             SettingsGroup(title = { |             SettingsGroup(title = { | ||||||
|                 SettingsTitleTextComponent(text = stringResource(id = R.string.general_settings)) |                 SettingsTitleTextComponent(text = stringResource(id = R.string.general_settings)) | ||||||
|             }) { |             }) { | ||||||
|                 SettingsPreferenceComponent(preferenceTitle = stringResource(id = R.string.purchase_simple_thank_you)) |                 if (!isOrWasThankYouInstalled) { | ||||||
|                 SettingsCheckBoxComponent(title = stringResource(id = R.string.use_english_language)) |                     SettingsPreferenceComponent(preferenceTitle = stringResource(id = R.string.purchase_simple_thank_you), doOnPreferenceClick = onThankYou) | ||||||
|                 SettingsPreferenceComponent(preferenceTitle = stringResource(id = R.string.language), preferenceSummary = "English") |                 } | ||||||
|                 SettingsCheckBoxComponent(title = stringResource(id = R.string.vibrate_on_button_press)) |                 if (isUseEnglishEnabled) { | ||||||
|                 SettingsCheckBoxComponent(title = stringResource(id = R.string.prevent_phone_from_sleeping)) |                     SettingsCheckBoxComponent( | ||||||
|                 SettingsCheckBoxComponent(title = stringResource(id = com.simplemobiletools.calculator.R.string.use_comma_as_decimal_mark)) |                         title = stringResource(id = R.string.use_english_language), | ||||||
|  |                         initialValue = isUseEnglishChecked, | ||||||
|  |                         onChange = onUseEnglishPress | ||||||
|  |                     ) | ||||||
|  |                 } | ||||||
|  |                 if (isTiramisuPlus()) { | ||||||
|  |                     SettingsPreferenceComponent( | ||||||
|  |                         preferenceTitle = stringResource(id = R.string.language), | ||||||
|  |                         preferenceSummary = displayLanguage, | ||||||
|  |                         doOnPreferenceClick = onSetupLanguagePress | ||||||
|  |                     ) | ||||||
|  |                 } | ||||||
|  |                 SettingsCheckBoxComponent( | ||||||
|  |                     title = stringResource(id = R.string.vibrate_on_button_press), | ||||||
|  |                     initialValue = vibrateOnButtonPressFlow, | ||||||
|  |                     onChange = onVibrateOnButtonPressFlow | ||||||
|  |                 ) | ||||||
|  |                 SettingsCheckBoxComponent( | ||||||
|  |                     title = stringResource(id = R.string.prevent_phone_from_sleeping), | ||||||
|  |                     initialValue = preventPhoneFromSleeping, | ||||||
|  |                     onChange = onPreventPhoneFromSleeping | ||||||
|  |                 ) | ||||||
|  |                 SettingsCheckBoxComponent( | ||||||
|  |                     title = stringResource(id = com.simplemobiletools.calculator.R.string.use_comma_as_decimal_mark), | ||||||
|  |                     initialValue = useCommaAsDecimalMarkFlow, | ||||||
|  |                     onChange = onUseCommaAsDecimalMarkFlow | ||||||
|  |                 ) | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @@ -89,5 +156,24 @@ fun SettingsScreen( | |||||||
| @MyDevices | @MyDevices | ||||||
| @Composable | @Composable | ||||||
| private fun SettingsScreenPreview() { | private fun SettingsScreenPreview() { | ||||||
|     AppThemeSurface { SettingsScreen(goBack = {}, customizeColors = {}) } |     AppThemeSurface { | ||||||
|  |         SettingsScreen( | ||||||
|  |             goBack = {}, | ||||||
|  |             customizeColors = {}, | ||||||
|  |             customizeWidgetColors = {}, | ||||||
|  |             preventPhoneFromSleeping = false, | ||||||
|  |             onPreventPhoneFromSleeping = {}, | ||||||
|  |             vibrateOnButtonPressFlow = false, | ||||||
|  |             onVibrateOnButtonPressFlow = {}, | ||||||
|  |             isOrWasThankYouInstalled = false, | ||||||
|  |             onThankYou = {}, | ||||||
|  |             topBarsScrolledContainerColor = MaterialTheme.colorScheme.primary, | ||||||
|  |             nonScrolledTextColor = Color.White, | ||||||
|  |             scrolledTextColor = Color.Black, | ||||||
|  |             isUseEnglishEnabled = false, | ||||||
|  |             isUseEnglishChecked = false, | ||||||
|  |             onUseEnglishPress = {}, | ||||||
|  |             onSetupLanguagePress = {}, useCommaAsDecimalMarkFlow = false, onUseCommaAsDecimalMarkFlow = {} | ||||||
|  |         ) | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,12 +1,17 @@ | |||||||
| package com.simplemobiletools.calculator.compose.theme | package com.simplemobiletools.calculator.compose.theme | ||||||
|  |  | ||||||
| import android.content.Context | import android.content.Context | ||||||
|  | import androidx.compose.runtime.Composable | ||||||
| import androidx.compose.ui.graphics.Color | import androidx.compose.ui.graphics.Color | ||||||
| import androidx.compose.ui.graphics.toArgb | import androidx.compose.ui.graphics.toArgb | ||||||
|  | import androidx.compose.ui.platform.LocalContext | ||||||
| import com.simplemobiletools.calculator.extensions.config | import com.simplemobiletools.calculator.extensions.config | ||||||
| import com.simplemobiletools.commons.extensions.isBlackAndWhiteTheme | import com.simplemobiletools.commons.extensions.isBlackAndWhiteTheme | ||||||
| import com.simplemobiletools.commons.extensions.isWhiteTheme | import com.simplemobiletools.commons.extensions.isWhiteTheme | ||||||
|  |  | ||||||
|  | @Composable | ||||||
|  | fun getCurrentTheme() = getTheme(LocalContext.current, Theme.systemDefaultMaterialYou()) | ||||||
|  |  | ||||||
| fun getTheme(context: Context, materialYouTheme: Theme.SystemDefaultMaterialYou): Theme { | fun getTheme(context: Context, materialYouTheme: Theme.SystemDefaultMaterialYou): Theme { | ||||||
|     val baseConfig = context.config |     val baseConfig = context.config | ||||||
|     val primaryColorInt = baseConfig.primaryColor |     val primaryColorInt = baseConfig.primaryColor | ||||||
|   | |||||||
| @@ -1,11 +1,11 @@ | |||||||
| package com.simplemobiletools.calculator.compose.theme | package com.simplemobiletools.calculator.compose.theme | ||||||
|  |  | ||||||
|  | import android.app.Activity | ||||||
| import android.app.ActivityManager | import android.app.ActivityManager | ||||||
| import android.content.Context | import android.content.Context | ||||||
| import android.content.res.Configuration | import android.content.res.Configuration | ||||||
| import android.graphics.BitmapFactory | import android.graphics.BitmapFactory | ||||||
| import android.os.Build | import android.os.Build | ||||||
| import android.util.Log |  | ||||||
| import androidx.compose.foundation.LocalOverscrollConfiguration | import androidx.compose.foundation.LocalOverscrollConfiguration | ||||||
| import androidx.compose.foundation.isSystemInDarkTheme | import androidx.compose.foundation.isSystemInDarkTheme | ||||||
| import androidx.compose.foundation.layout.fillMaxSize | import androidx.compose.foundation.layout.fillMaxSize | ||||||
| @@ -26,12 +26,12 @@ import com.simplemobiletools.calculator.compose.theme.Theme.Companion.systemDefa | |||||||
| import com.simplemobiletools.calculator.extensions.config | import com.simplemobiletools.calculator.extensions.config | ||||||
| import com.simplemobiletools.calculator.helpers.Config | import com.simplemobiletools.calculator.helpers.Config | ||||||
| import com.simplemobiletools.commons.R | import com.simplemobiletools.commons.R | ||||||
| import com.simplemobiletools.commons.extensions.* | import com.simplemobiletools.commons.extensions.adjustAlpha | ||||||
| import com.simplemobiletools.commons.helpers.APP_ICON_IDS | import com.simplemobiletools.commons.helpers.APP_ICON_IDS | ||||||
| import com.simplemobiletools.commons.helpers.APP_LAUNCHER_NAME | import com.simplemobiletools.commons.helpers.APP_LAUNCHER_NAME | ||||||
| import com.simplemobiletools.commons.helpers.HIGHER_ALPHA | import com.simplemobiletools.commons.helpers.HIGHER_ALPHA | ||||||
|  |  | ||||||
| private val DarkColorScheme = darkColorScheme( | private val darkColorScheme = darkColorScheme( | ||||||
|     primary = color_primary, |     primary = color_primary, | ||||||
|     secondary = color_primary_dark, |     secondary = color_primary_dark, | ||||||
|     tertiary = color_accent, |     tertiary = color_accent, | ||||||
| @@ -112,6 +112,7 @@ sealed class Theme : CommonTheme { | |||||||
|         override val textColorInt: Int |         override val textColorInt: Int | ||||||
|     ) : Theme() |     ) : Theme() | ||||||
|  |  | ||||||
|  |  | ||||||
|     companion object { |     companion object { | ||||||
|         @Composable |         @Composable | ||||||
|         fun systemDefaultMaterialYou() = SystemDefaultMaterialYou( |         fun systemDefaultMaterialYou() = SystemDefaultMaterialYou( | ||||||
| @@ -125,7 +126,25 @@ sealed class Theme : CommonTheme { | |||||||
|  |  | ||||||
| @Composable | @Composable | ||||||
| @ReadOnlyComposable | @ReadOnlyComposable | ||||||
| private fun isInDarkThemeAndSurfaceIsNotLitWell() = isSystemInDarkTheme() || MaterialTheme.colorScheme.surface.luminance() < 0.5 | fun isInDarkThemeAndSurfaceIsNotLitWell() = isSystemInDarkTheme() || isSurfaceNotLitWell() | ||||||
|  |  | ||||||
|  | private const val LUMINANCE_THRESHOLD = 0.5f | ||||||
|  |  | ||||||
|  | @Composable | ||||||
|  | @ReadOnlyComposable | ||||||
|  | fun isSurfaceNotLitWell() = MaterialTheme.colorScheme.surface.luminance() < LUMINANCE_THRESHOLD | ||||||
|  |  | ||||||
|  | @Composable | ||||||
|  | @ReadOnlyComposable | ||||||
|  | fun isSurfaceLitWell() = MaterialTheme.colorScheme.surface.luminance() > LUMINANCE_THRESHOLD | ||||||
|  |  | ||||||
|  | @Composable | ||||||
|  | @ReadOnlyComposable | ||||||
|  | fun Color.isLitWell() = luminance() > LUMINANCE_THRESHOLD | ||||||
|  |  | ||||||
|  | @Composable | ||||||
|  | @ReadOnlyComposable | ||||||
|  | fun Color.isNotLitWell() = luminance() < LUMINANCE_THRESHOLD | ||||||
|  |  | ||||||
|  |  | ||||||
| @Composable | @Composable | ||||||
| @@ -163,7 +182,7 @@ fun Theme( | |||||||
|             onSurface = theme.textColor |             onSurface = theme.textColor | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|         else -> DarkColorScheme |         else -> darkColorScheme | ||||||
|     } |     } | ||||||
|     LaunchedEffect(Unit) { |     LaunchedEffect(Unit) { | ||||||
|         /* if (context.navigationBarHeight > 0 || context.isUsingGestureNavigation() && useTransparentNavigation) { |         /* if (context.navigationBarHeight > 0 || context.isUsingGestureNavigation() && useTransparentNavigation) { | ||||||
| @@ -205,8 +224,10 @@ fun Theme( | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| private fun Context.getAppIconIds(): List<Int> = getActivity().intent.getIntegerArrayListExtra(APP_ICON_IDS).orEmpty() | private fun Context.getAppIconIds(): List<Int> = getActivity().getAppIconIds() | ||||||
| private fun Context.getAppLauncherName(): String = getActivity().intent.getStringExtra(APP_LAUNCHER_NAME).orEmpty() | fun Activity.getAppIconIds(): ArrayList<Int> = ArrayList(intent.getIntegerArrayListExtra(APP_ICON_IDS).orEmpty()) | ||||||
|  | private fun Context.getAppLauncherName(): String = getActivity().getAppLauncherName() | ||||||
|  | fun Activity.getAppLauncherName(): String = intent.getStringExtra(APP_LAUNCHER_NAME).orEmpty() | ||||||
| private fun updateRecentsAppIcon(baseConfig: Config, context: Context) { | private fun updateRecentsAppIcon(baseConfig: Config, context: Context) { | ||||||
|     if (baseConfig.isUsingModifiedAppIcon) { |     if (baseConfig.isUsingModifiedAppIcon) { | ||||||
|         val appIconIDs = context.getAppIconIds() |         val appIconIDs = context.getAppIconIds() | ||||||
|   | |||||||
| @@ -4,13 +4,18 @@ import android.appwidget.AppWidgetManager | |||||||
| import android.content.ComponentName | import android.content.ComponentName | ||||||
| import android.content.Context | import android.content.Context | ||||||
| import android.content.Intent | import android.content.Intent | ||||||
|  | import android.net.Uri | ||||||
|  | import android.os.Build | ||||||
|  | import android.provider.Settings | ||||||
| import android.view.ViewGroup | import android.view.ViewGroup | ||||||
| import android.widget.Button | import android.widget.Button | ||||||
| import android.widget.TextView | import android.widget.TextView | ||||||
|  | import androidx.annotation.RequiresApi | ||||||
| import com.simplemobiletools.calculator.databases.CalculatorDatabase | import com.simplemobiletools.calculator.databases.CalculatorDatabase | ||||||
| import com.simplemobiletools.calculator.helpers.Config | import com.simplemobiletools.calculator.helpers.Config | ||||||
| import com.simplemobiletools.calculator.helpers.MyWidgetProvider | import com.simplemobiletools.calculator.helpers.MyWidgetProvider | ||||||
| import com.simplemobiletools.calculator.interfaces.CalculatorDao | import com.simplemobiletools.calculator.interfaces.CalculatorDao | ||||||
|  | import com.simplemobiletools.commons.extensions.showErrorToast | ||||||
|  |  | ||||||
| val Context.config: Config get() = Config.newInstance(applicationContext) | val Context.config: Config get() = Config.newInstance(applicationContext) | ||||||
|  |  | ||||||
| @@ -40,3 +45,22 @@ fun Context.updateWidgets() { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @RequiresApi(Build.VERSION_CODES.TIRAMISU) | ||||||
|  | fun Context.launchChangeAppLanguageIntent() { | ||||||
|  |     try { | ||||||
|  |         Intent(Settings.ACTION_APP_LOCALE_SETTINGS).apply { | ||||||
|  |             data = Uri.fromParts("package", packageName, null) | ||||||
|  |             startActivity(this) | ||||||
|  |         } | ||||||
|  |     } catch (e: Exception) { | ||||||
|  |         try { | ||||||
|  |             Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply { | ||||||
|  |                 data = Uri.fromParts("package", packageName, null) | ||||||
|  |                 startActivity(this) | ||||||
|  |             } | ||||||
|  |         } catch (e: Exception) { | ||||||
|  |             showErrorToast(e) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|   | |||||||
| @@ -0,0 +1,18 @@ | |||||||
|  | package com.simplemobiletools.calculator.extensions | ||||||
|  |  | ||||||
|  | import android.content.SharedPreferences | ||||||
|  | import kotlinx.coroutines.channels.awaitClose | ||||||
|  | import kotlinx.coroutines.flow.callbackFlow | ||||||
|  |  | ||||||
|  | context (SharedPreferences) | ||||||
|  | fun <T> sharedPreferencesCallback( | ||||||
|  |     value: () -> T?, | ||||||
|  | ) = callbackFlow { | ||||||
|  |     val sharedPreferencesListener = | ||||||
|  |         SharedPreferences.OnSharedPreferenceChangeListener { _, _ -> | ||||||
|  |             trySend(value()) | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     registerOnSharedPreferenceChangeListener(sharedPreferencesListener) | ||||||
|  |     awaitClose { unregisterOnSharedPreferenceChangeListener(sharedPreferencesListener) } | ||||||
|  | } | ||||||
| @@ -1,7 +1,10 @@ | |||||||
| package com.simplemobiletools.calculator.helpers | package com.simplemobiletools.calculator.helpers | ||||||
|  |  | ||||||
| import android.content.Context | import android.content.Context | ||||||
|  | import com.simplemobiletools.calculator.extensions.sharedPreferencesCallback | ||||||
| import com.simplemobiletools.commons.helpers.BaseConfig | import com.simplemobiletools.commons.helpers.BaseConfig | ||||||
|  | import kotlinx.coroutines.flow.Flow | ||||||
|  | import kotlinx.coroutines.flow.filterNotNull | ||||||
|  |  | ||||||
| class Config(context: Context) : BaseConfig(context) { | class Config(context: Context) : BaseConfig(context) { | ||||||
|     companion object { |     companion object { | ||||||
| @@ -11,4 +14,10 @@ class Config(context: Context) : BaseConfig(context) { | |||||||
|     var useCommaAsDecimalMark: Boolean |     var useCommaAsDecimalMark: Boolean | ||||||
|         get() = prefs.getBoolean(USE_COMMA_AS_DECIMAL_MARK, getDecimalSeparator() == COMMA) |         get() = prefs.getBoolean(USE_COMMA_AS_DECIMAL_MARK, getDecimalSeparator() == COMMA) | ||||||
|         set(useCommaAsDecimalMark) = prefs.edit().putBoolean(USE_COMMA_AS_DECIMAL_MARK, useCommaAsDecimalMark).apply() |         set(useCommaAsDecimalMark) = prefs.edit().putBoolean(USE_COMMA_AS_DECIMAL_MARK, useCommaAsDecimalMark).apply() | ||||||
|  |  | ||||||
|  |     val preventPhoneFromSleepingFlow: Flow<Boolean> = prefs.run { sharedPreferencesCallback { preventPhoneFromSleeping } }.filterNotNull() | ||||||
|  |     val vibrateOnButtonPressFlow: Flow<Boolean> = prefs.run { sharedPreferencesCallback { vibrateOnButtonPress } }.filterNotNull() | ||||||
|  |     val wasUseEnglishToggledFlow: Flow<Boolean> = prefs.run { sharedPreferencesCallback { wasUseEnglishToggled } }.filterNotNull() | ||||||
|  |     val useEnglishFlow: Flow<Boolean> = prefs.run { sharedPreferencesCallback { useEnglish } }.filterNotNull() | ||||||
|  |     val useCommaAsDecimalMarkFlow: Flow<Boolean> = prefs.run { sharedPreferencesCallback { useCommaAsDecimalMark } }.filterNotNull() | ||||||
| } | } | ||||||
|   | |||||||
| @@ -6,6 +6,7 @@ ksp = "1.8.22-1.0.11" | |||||||
| #Androidx | #Androidx | ||||||
| androidx-customView = "1.2.0-alpha02" | androidx-customView = "1.2.0-alpha02" | ||||||
| androidx-customViewPooling = "1.0.0" | androidx-customViewPooling = "1.0.0" | ||||||
|  | androidx-lifecycle = "2.6.1" | ||||||
| #Compose | #Compose | ||||||
| composeActivity = "1.8.0-alpha06" | composeActivity = "1.8.0-alpha06" | ||||||
| compose = "1.6.0-alpha01" | compose = "1.6.0-alpha01" | ||||||
| @@ -37,6 +38,11 @@ app-version-versionName = "5.11.3" | |||||||
| #Android X | #Android X | ||||||
| androidx-customView = { module = "androidx.customview:customview", version.ref = "androidx-customView" } | androidx-customView = { module = "androidx.customview:customview", version.ref = "androidx-customView" } | ||||||
| androidx-customViewPooling = { module = "androidx.customview:customview-poolingcontainer", version.ref = "androidx-customViewPooling" } | androidx-customViewPooling = { module = "androidx.customview:customview-poolingcontainer", version.ref = "androidx-customViewPooling" } | ||||||
|  | #Android X lifecycle | ||||||
|  | androidx-lifecycle-runtime = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "androidx-lifecycle" } | ||||||
|  | androidx-lifecycle-viewModel = { module = "androidx.lifecycle:lifecycle-viewmodel-ktx", version.ref = "androidx-lifecycle" } | ||||||
|  | androidx-lifecycle-viewModel-compose = { module = "androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "androidx-lifecycle" } | ||||||
|  | androidx-lifecycle-compose = { module = "androidx.lifecycle:lifecycle-runtime-compose", version.ref = "androidx-lifecycle" } | ||||||
| #Room | #Room | ||||||
| androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" } | androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" } | ||||||
| androidx-room-ktx = { module = "androidx.room:room-ktx", version.ref = "room" } | androidx-room-ktx = { module = "androidx.room:room-ktx", version.ref = "room" } | ||||||
| @@ -85,7 +91,12 @@ room = [ | |||||||
| accompanist = [ | accompanist = [ | ||||||
|     "accompanist-systemuicontroller", |     "accompanist-systemuicontroller", | ||||||
| ] | ] | ||||||
|  | lifecycle = [ | ||||||
|  |     "androidx-lifecycle-compose", | ||||||
|  |     "androidx-lifecycle-runtime", | ||||||
|  |     "androidx-lifecycle-viewModel", | ||||||
|  |     "androidx-lifecycle-viewModel-compose", | ||||||
|  | ] | ||||||
| [plugins] | [plugins] | ||||||
| android = { id = "com.android.application", version.ref = "gradlePlugins-agp" } | android = { id = "com.android.application", version.ref = "gradlePlugins-agp" } | ||||||
| ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } | ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user