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