fully implement the compose theming and hook up the settings logic

This commit is contained in:
FunkyMuse
2023-07-06 20:16:52 +02:00
parent 3b72df5844
commit e966dc0b43
9 changed files with 257 additions and 107 deletions

View File

@ -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)

View File

@ -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)
} }
} }
} }
}

View File

@ -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 = {}
)
}
} }

View File

@ -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

View File

@ -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()

View File

@ -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)
}
}
}

View File

@ -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) }
}

View File

@ -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()
} }

View File

@ -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" }