diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 1a737c43..9271a224 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -18,8 +18,8 @@ android { applicationId = "com.aliernfrog.pftool" minSdk = 23 targetSdk = 34 - versionCode = 17100 - versionName = "1.7.1" + versionCode = 17200 + versionName = "1.7.2" vectorDrawables { useSupportLibrary = true } } diff --git a/app/src/main/java/com/aliernfrog/pftool/ui/activity/MainActivity.kt b/app/src/main/java/com/aliernfrog/pftool/ui/activity/MainActivity.kt index c338227f..a90074ca 100644 --- a/app/src/main/java/com/aliernfrog/pftool/ui/activity/MainActivity.kt +++ b/app/src/main/java/com/aliernfrog/pftool/ui/activity/MainActivity.kt @@ -51,6 +51,7 @@ class MainActivity : AppCompatActivity() { PFToolTheme( darkTheme = useDarkTheme, dynamicColors = mainViewModel.prefs.materialYou, + pitchBlack = mainViewModel.prefs.pitchBlack, content = content ) } diff --git a/app/src/main/java/com/aliernfrog/pftool/ui/component/form/ButtonRow.kt b/app/src/main/java/com/aliernfrog/pftool/ui/component/form/ButtonRow.kt index 74639edb..0be72aef 100644 --- a/app/src/main/java/com/aliernfrog/pftool/ui/component/form/ButtonRow.kt +++ b/app/src/main/java/com/aliernfrog/pftool/ui/component/form/ButtonRow.kt @@ -2,7 +2,6 @@ package com.aliernfrog.pftool.ui.component.form import androidx.compose.animation.core.animateFloatAsState import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons import androidx.compose.material.icons.rounded.KeyboardArrowUp @@ -28,7 +27,6 @@ fun ButtonRow( arrowRotation: Float = if (expanded == true) 0f else 180f, trailingComponent: @Composable (() -> Unit)? = null, shape: Shape = RectangleShape, - contentPadding: PaddingValues = PaddingValues(0.dp), containerColor: Color = Color.Transparent, contentColor: Color = if (containerColor == Color.Transparent) MaterialTheme.colorScheme.onSurface @@ -42,7 +40,6 @@ fun ButtonRow( description = description, painter = painter, shape = shape, - contentPadding = contentPadding, containerColor = containerColor, contentColor = contentColor, onClick = onClick diff --git a/app/src/main/java/com/aliernfrog/pftool/ui/component/form/FormHeader.kt b/app/src/main/java/com/aliernfrog/pftool/ui/component/form/FormHeader.kt index c428d67f..e21448f5 100644 --- a/app/src/main/java/com/aliernfrog/pftool/ui/component/form/FormHeader.kt +++ b/app/src/main/java/com/aliernfrog/pftool/ui/component/form/FormHeader.kt @@ -1,11 +1,10 @@ package com.aliernfrog.pftool.ui.component.form import androidx.compose.animation.animateContentSize +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text @@ -14,7 +13,9 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp @Composable fun FormHeader( @@ -32,28 +33,30 @@ fun FormHeader( Icon( painter = painter, contentDescription = null, - modifier = Modifier.size(30.dp).padding(1.dp), + modifier = Modifier.padding(end = 18.dp), tint = contentColor ) } Column( - modifier = Modifier - .padding(vertical = 4.dp, horizontal = 8.dp) + verticalArrangement = Arrangement.spacedBy(2.dp) ) { Text( text = title, color = contentColor, - style = MaterialTheme.typography.titleMedium, - modifier = Modifier.fillMaxWidth() + style = MaterialTheme.typography.titleLarge.copy( + fontWeight = FontWeight.Normal, + fontSize = 19.sp + ), + modifier = Modifier.animateContentSize() ) description?.let { Text( text = description, color = contentColor, - style = MaterialTheme.typography.bodyMedium, - modifier = Modifier - .fillMaxWidth() - .animateContentSize() + style = MaterialTheme.typography.bodyMedium.copy( + color = MaterialTheme.colorScheme.onSurface.copy(0.6f) + ), + modifier = Modifier.animateContentSize() ) } } diff --git a/app/src/main/java/com/aliernfrog/pftool/ui/component/form/FormRow.kt b/app/src/main/java/com/aliernfrog/pftool/ui/component/form/FormRow.kt index 592ca469..78aa065e 100644 --- a/app/src/main/java/com/aliernfrog/pftool/ui/component/form/FormRow.kt +++ b/app/src/main/java/com/aliernfrog/pftool/ui/component/form/FormRow.kt @@ -1,7 +1,6 @@ package com.aliernfrog.pftool.ui.component.form import androidx.compose.foundation.background -import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.heightIn @@ -26,7 +25,6 @@ fun FormRow( description: String? = null, painter: Painter? = null, shape: Shape = RectangleShape, - contentPadding: PaddingValues = PaddingValues(0.dp), containerColor: Color = Color.Transparent, contentColor: Color = if (containerColor == Color.Transparent) MaterialTheme.colorScheme.onSurface else contentColorFor(containerColor), @@ -35,16 +33,15 @@ fun FormRow( ) { Row( modifier = modifier - .fillMaxWidth() .heightIn(56.dp) + .fillMaxWidth() .clip(shape) .background(containerColor) .clickableWithColor( color = contentColor, onClick = onClick ) - .padding(horizontal = 8.dp, vertical = 4.dp) - .padding(contentPadding), + .padding(end = 9.dp), verticalAlignment = Alignment.CenterVertically ) { FormHeader( @@ -55,6 +52,10 @@ fun FormRow( modifier = Modifier .fillMaxWidth() .weight(1f) + .padding( + vertical = 8.dp, + horizontal = 18.dp + ) ) content() } diff --git a/app/src/main/java/com/aliernfrog/pftool/ui/component/form/SwitchRow.kt b/app/src/main/java/com/aliernfrog/pftool/ui/component/form/SwitchRow.kt index 724bd960..33c5485d 100644 --- a/app/src/main/java/com/aliernfrog/pftool/ui/component/form/SwitchRow.kt +++ b/app/src/main/java/com/aliernfrog/pftool/ui/component/form/SwitchRow.kt @@ -18,6 +18,7 @@ fun SwitchRow( modifier: Modifier = Modifier, description: String? = null, painter: Painter? = null, + enabled: Boolean = true, shape: Shape = RectangleShape, containerColor: Color = Color.Transparent, contentColor: Color = MaterialTheme.colorScheme.onSurface, @@ -30,14 +31,17 @@ fun SwitchRow( painter = painter, shape = shape, containerColor = containerColor, - contentColor = contentColor, + contentColor = contentColor.let { + if (enabled) it else it.copy(alpha = 0.7f) + }, onClick = { - onCheckedChange(!checked) + if (enabled) onCheckedChange(!checked) } ) { Switch( checked = checked, onCheckedChange = onCheckedChange, + enabled = enabled, modifier = Modifier.padding(horizontal = 8.dp) ) } diff --git a/app/src/main/java/com/aliernfrog/pftool/ui/component/MapButton.kt b/app/src/main/java/com/aliernfrog/pftool/ui/component/maps/MapButton.kt similarity index 81% rename from app/src/main/java/com/aliernfrog/pftool/ui/component/MapButton.kt rename to app/src/main/java/com/aliernfrog/pftool/ui/component/maps/MapButton.kt index 2887ac23..2357e2f0 100644 --- a/app/src/main/java/com/aliernfrog/pftool/ui/component/MapButton.kt +++ b/app/src/main/java/com/aliernfrog/pftool/ui/component/maps/MapButton.kt @@ -1,10 +1,8 @@ -package com.aliernfrog.pftool.ui.component +package com.aliernfrog.pftool.ui.component.maps import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.IntrinsicSize import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding @@ -13,6 +11,10 @@ import androidx.compose.material.icons.outlined.PinDrop import androidx.compose.material3.MaterialTheme import androidx.compose.material3.contentColorFor import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -21,12 +23,13 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.painter.ColorPainter import androidx.compose.ui.graphics.vector.rememberVectorPainter import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.layout.onSizeChanged +import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.unit.LayoutDirection import androidx.compose.ui.unit.dp import coil.compose.AsyncImage import com.aliernfrog.pftool.impl.MapFile -import com.aliernfrog.pftool.ui.component.form.FormHeader import com.aliernfrog.pftool.ui.theme.AppComponentShape import com.aliernfrog.pftool.util.extension.combinedClickableWithColor @@ -41,6 +44,9 @@ fun MapButton( onLongClick: () -> Unit = {}, onClick: () -> Unit ) { + val density = LocalDensity.current + var headerHeight by remember { mutableStateOf(0.dp) } + val isRTL = LocalLayoutDirection.current == LayoutDirection.Rtl fun invertIfRTL(list: List): List { return if (isRTL) list.reversed() else list @@ -49,7 +55,6 @@ fun MapButton( Box( modifier = modifier .fillMaxWidth() - .height(IntrinsicSize.Max) .padding(8.dp) .clip(AppComponentShape) .background(containerColor) @@ -62,7 +67,7 @@ fun MapButton( if (showMapThumbnail) AsyncImage( model = map.thumbnailModel, contentDescription = null, - modifier = Modifier.fillMaxWidth(), + modifier = Modifier.height(headerHeight).fillMaxWidth(), placeholder = ColorPainter(containerColor), error = ColorPainter(containerColor), fallback = ColorPainter(containerColor), @@ -77,12 +82,17 @@ fun MapButton( ) )) ) { - FormHeader( + MapHeader( title = map.name, description = map.details, painter = rememberVectorPainter(Icons.Outlined.PinDrop), modifier = Modifier - .fillMaxSize() + .onSizeChanged { + density.run { + headerHeight = it.height.toDp() + } + } + .fillMaxWidth() .padding(horizontal = 8.dp, vertical = 4.dp) .weight(1f) ) diff --git a/app/src/main/java/com/aliernfrog/pftool/ui/component/maps/MapHeader.kt b/app/src/main/java/com/aliernfrog/pftool/ui/component/maps/MapHeader.kt new file mode 100644 index 00000000..3aa6e97b --- /dev/null +++ b/app/src/main/java/com/aliernfrog/pftool/ui/component/maps/MapHeader.kt @@ -0,0 +1,61 @@ +package com.aliernfrog.pftool.ui.component.maps + +import androidx.compose.animation.animateContentSize +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.unit.dp + +@Composable +fun MapHeader( + title: String, + modifier: Modifier = Modifier, + description: String? = null, + painter: Painter? = null, + contentColor: Color = MaterialTheme.colorScheme.onSurface +) { + Row( + modifier = modifier, + verticalAlignment = Alignment.CenterVertically + ) { + painter?.let { + Icon( + painter = painter, + contentDescription = null, + modifier = Modifier.size(30.dp).padding(1.dp), + tint = contentColor + ) + } + Column( + modifier = Modifier + .padding(vertical = 4.dp, horizontal = 8.dp) + ) { + Text( + text = title, + color = contentColor, + style = MaterialTheme.typography.titleMedium, + modifier = Modifier.fillMaxWidth() + ) + description?.let { + Text( + text = description, + color = contentColor, + style = MaterialTheme.typography.bodyMedium, + modifier = Modifier + .fillMaxWidth() + .animateContentSize() + ) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/aliernfrog/pftool/ui/component/PickMapButton.kt b/app/src/main/java/com/aliernfrog/pftool/ui/component/maps/PickMapButton.kt similarity index 96% rename from app/src/main/java/com/aliernfrog/pftool/ui/component/PickMapButton.kt rename to app/src/main/java/com/aliernfrog/pftool/ui/component/maps/PickMapButton.kt index ff77086e..be4a76b8 100644 --- a/app/src/main/java/com/aliernfrog/pftool/ui/component/PickMapButton.kt +++ b/app/src/main/java/com/aliernfrog/pftool/ui/component/maps/PickMapButton.kt @@ -1,4 +1,4 @@ -package com.aliernfrog.pftool.ui.component +package com.aliernfrog.pftool.ui.component.maps import androidx.compose.animation.animateContentSize import androidx.compose.foundation.background @@ -23,7 +23,7 @@ import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.unit.dp import coil.compose.AsyncImage import com.aliernfrog.pftool.impl.MapFile -import com.aliernfrog.pftool.ui.component.form.FormHeader +import com.aliernfrog.pftool.ui.component.FadeVisibility import com.aliernfrog.pftool.ui.theme.AppComponentShape import com.aliernfrog.pftool.util.extension.clickableWithColor @@ -66,7 +66,7 @@ fun PickMapButton( .padding(horizontal = 8.dp), verticalAlignment = Alignment.CenterVertically ) { - FormHeader( + MapHeader( title = chosenMap?.name ?: "", description = chosenMap?.details, painter = rememberVectorPainter(Icons.Rounded.LocationOn), diff --git a/app/src/main/java/com/aliernfrog/pftool/ui/screen/maps/MapsListScreen.kt b/app/src/main/java/com/aliernfrog/pftool/ui/screen/maps/MapsListScreen.kt index 958ded68..c7559e3c 100644 --- a/app/src/main/java/com/aliernfrog/pftool/ui/screen/maps/MapsListScreen.kt +++ b/app/src/main/java/com/aliernfrog/pftool/ui/screen/maps/MapsListScreen.kt @@ -66,7 +66,7 @@ import com.aliernfrog.pftool.impl.MapFile import com.aliernfrog.pftool.ui.component.AppScaffold import com.aliernfrog.pftool.ui.component.AppTopBar import com.aliernfrog.pftool.ui.component.ErrorWithIcon -import com.aliernfrog.pftool.ui.component.MapButton +import com.aliernfrog.pftool.ui.component.maps.MapButton import com.aliernfrog.pftool.ui.component.SegmentedButtons import com.aliernfrog.pftool.ui.component.SettingsButton import com.aliernfrog.pftool.ui.component.form.DividerRow diff --git a/app/src/main/java/com/aliernfrog/pftool/ui/screen/maps/MapsScreen.kt b/app/src/main/java/com/aliernfrog/pftool/ui/screen/maps/MapsScreen.kt index cadfc95e..440cd156 100644 --- a/app/src/main/java/com/aliernfrog/pftool/ui/screen/maps/MapsScreen.kt +++ b/app/src/main/java/com/aliernfrog/pftool/ui/screen/maps/MapsScreen.kt @@ -43,7 +43,7 @@ import com.aliernfrog.pftool.ui.component.AppScaffold import com.aliernfrog.pftool.ui.component.AppTopBar import com.aliernfrog.pftool.ui.component.ButtonIcon import com.aliernfrog.pftool.ui.component.FadeVisibility -import com.aliernfrog.pftool.ui.component.PickMapButton +import com.aliernfrog.pftool.ui.component.maps.PickMapButton import com.aliernfrog.pftool.ui.component.SettingsButton import com.aliernfrog.pftool.ui.component.VerticalSegmentedButtons import com.aliernfrog.pftool.ui.component.form.ButtonRow diff --git a/app/src/main/java/com/aliernfrog/pftool/ui/screen/permissions/PermissionsScreen.kt b/app/src/main/java/com/aliernfrog/pftool/ui/screen/permissions/PermissionsScreen.kt index ff7f7d40..2ddd0211 100644 --- a/app/src/main/java/com/aliernfrog/pftool/ui/screen/permissions/PermissionsScreen.kt +++ b/app/src/main/java/com/aliernfrog/pftool/ui/screen/permissions/PermissionsScreen.kt @@ -19,6 +19,7 @@ import androidx.lifecycle.Lifecycle import androidx.lifecycle.compose.LifecycleEventEffect import com.aliernfrog.pftool.R import com.aliernfrog.pftool.data.PermissionData +import com.aliernfrog.pftool.documentsUIPackageName import com.aliernfrog.pftool.enum.StorageAccessType import com.aliernfrog.pftool.ui.component.AppScaffold import com.aliernfrog.pftool.ui.component.AppTopBar @@ -102,7 +103,7 @@ fun PermissionsScreen( permissionsViewModel.showFilesDowngradeDialog = false Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - data = Uri.parse("package:com.google.android.documentsui") + data = Uri.parse("package:$documentsUIPackageName") context.startActivity(this) } } diff --git a/app/src/main/java/com/aliernfrog/pftool/ui/screen/settings/AboutPage.kt b/app/src/main/java/com/aliernfrog/pftool/ui/screen/settings/AboutPage.kt index 32792e57..1848d833 100644 --- a/app/src/main/java/com/aliernfrog/pftool/ui/screen/settings/AboutPage.kt +++ b/app/src/main/java/com/aliernfrog/pftool/ui/screen/settings/AboutPage.kt @@ -14,7 +14,6 @@ import androidx.compose.foundation.rememberScrollState import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Refresh import androidx.compose.material.icons.filled.Update -import androidx.compose.material.icons.rounded.Done import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.ElevatedButton @@ -23,7 +22,6 @@ import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.LocalTextStyle import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedButton -import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable @@ -45,8 +43,6 @@ import androidx.core.graphics.drawable.toBitmap import com.aliernfrog.pftool.R import com.aliernfrog.pftool.SettingsConstant import com.aliernfrog.pftool.ui.component.ButtonIcon -import com.aliernfrog.pftool.ui.component.FadeVisibility -import com.aliernfrog.pftool.ui.component.form.ButtonRow import com.aliernfrog.pftool.ui.component.form.FormSection import com.aliernfrog.pftool.ui.component.form.SwitchRow import com.aliernfrog.pftool.ui.theme.AppComponentShape @@ -54,7 +50,6 @@ import com.aliernfrog.pftool.ui.viewmodel.MainViewModel import com.aliernfrog.pftool.ui.viewmodel.SettingsViewModel import com.aliernfrog.pftool.util.extension.horizontalFadingEdge import com.aliernfrog.pftool.util.extension.resolveString -import com.aliernfrog.pftool.util.staticutil.GeneralUtil import dev.jeziellago.compose.markdowntext.MarkdownText import kotlinx.coroutines.launch import org.koin.androidx.compose.koinViewModel @@ -174,10 +169,6 @@ fun AboutPage( settingsViewModel.prefs.autoCheckUpdates = it } - FadeVisibility(settingsViewModel.experimentalSettingsShown) { - ExperimentalSettings() - } - FormSection( title = stringResource(R.string.settings_about_changelog), topDivider = true, @@ -204,87 +195,6 @@ fun AboutPage( } } -@OptIn(ExperimentalMaterial3Api::class) -@Composable -private fun ExperimentalSettings( - mainViewModel: MainViewModel = koinViewModel(), - settingsViewModel: SettingsViewModel = koinViewModel() -) { - val context = LocalContext.current - val scope = rememberCoroutineScope() - FormSection( - title = stringResource(R.string.settings_experimental), - bottomDivider = false, - topDivider = true - ) { - Text( - text = stringResource(R.string.settings_experimental_description), - color = MaterialTheme.colorScheme.error, - modifier = Modifier.padding(horizontal = 16.dp) - ) - SwitchRow( - title = stringResource(R.string.settings_experimental_showMaterialYouOption), - checked = settingsViewModel.showMaterialYouOption, - onCheckedChange = { - settingsViewModel.showMaterialYouOption = it - } - ) - SwitchRow( - title = stringResource(R.string.settings_experimental_showMapNameFieldGuide), - checked = settingsViewModel.prefs.showMapNameFieldGuide, - onCheckedChange = { - settingsViewModel.prefs.showMapNameFieldGuide = it - } - ) - ButtonRow( - title = stringResource(R.string.settings_experimental_checkUpdates) - ) { - scope.launch { - mainViewModel.checkUpdates(ignoreVersion = true) - } - } - ButtonRow( - title = stringResource(R.string.settings_experimental_showUpdateToast) - ) { - mainViewModel.showUpdateToast() - } - ButtonRow( - title = stringResource(R.string.settings_experimental_showUpdateDialog) - ) { - scope.launch { - mainViewModel.updateSheetState.show() - } - } - SettingsConstant.experimentalPrefOptions.forEach { prefEdit -> - OutlinedTextField( - value = prefEdit.getValue(settingsViewModel.prefs), - onValueChange = { - prefEdit.setValue(it, settingsViewModel.prefs) - }, - label = { - Text(stringResource(prefEdit.labelResourceId)) - }, - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp, vertical = 8.dp) - ) - } - ButtonRow( - title = stringResource(R.string.settings_experimental_resetPrefs), - contentColor = MaterialTheme.colorScheme.error - ) { - SettingsConstant.experimentalPrefOptions.forEach { - it.setValue(it.default, settingsViewModel.prefs) - } - settingsViewModel.topToastState.showAndroidToast( - text = R.string.settings_experimental_resetPrefsDone, - icon = Icons.Rounded.Done - ) - GeneralUtil.restartApp(context) - } - } -} - @Composable private fun UpdateButton( updateAvailable: Boolean, diff --git a/app/src/main/java/com/aliernfrog/pftool/ui/screen/settings/AppearancePage.kt b/app/src/main/java/com/aliernfrog/pftool/ui/screen/settings/AppearancePage.kt index a1039370..d5477192 100644 --- a/app/src/main/java/com/aliernfrog/pftool/ui/screen/settings/AppearancePage.kt +++ b/app/src/main/java/com/aliernfrog/pftool/ui/screen/settings/AppearancePage.kt @@ -1,20 +1,21 @@ package com.aliernfrog.pftool.ui.screen.settings +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.Brush -import androidx.compose.material.icons.outlined.DarkMode +import androidx.compose.material.icons.outlined.Contrast import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.saveable.rememberSaveable -import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.rememberVectorPainter import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp import com.aliernfrog.pftool.R -import com.aliernfrog.pftool.ui.component.RadioButtons -import com.aliernfrog.pftool.ui.component.form.ExpandableRow +import com.aliernfrog.pftool.ui.component.SegmentedButtons +import com.aliernfrog.pftool.ui.component.form.FormSection import com.aliernfrog.pftool.ui.component.form.SwitchRow import com.aliernfrog.pftool.ui.theme.Theme +import com.aliernfrog.pftool.ui.theme.supportsMaterialYou import com.aliernfrog.pftool.ui.viewmodel.SettingsViewModel import org.koin.androidx.compose.koinViewModel @@ -23,38 +24,47 @@ fun AppearancePage( settingsViewModel: SettingsViewModel = koinViewModel(), onNavigateBackRequest: () -> Unit ) { - var themeOptionsExpanded by rememberSaveable { - mutableStateOf(false) - } - SettingsPageContainer( title = stringResource(R.string.settings_appearance), onNavigateBackRequest = onNavigateBackRequest ) { - ExpandableRow( - expanded = themeOptionsExpanded, - title = stringResource(R.string.settings_appearance_theme), - description = stringResource(R.string.settings_appearance_theme_description), - painter = rememberVectorPainter(Icons.Outlined.DarkMode), - trailingButtonText = stringResource(Theme.entries[settingsViewModel.prefs.theme].label), - onClickHeader = { - themeOptionsExpanded = !themeOptionsExpanded - } + FormSection( + title = stringResource(R.string.settings_appearance_theme) ) { - RadioButtons( + SegmentedButtons( options = Theme.entries.map { stringResource(it.label) }, - selectedOptionIndex = settingsViewModel.prefs.theme + selectedIndex = settingsViewModel.prefs.theme, + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp) ) { settingsViewModel.prefs.theme = it } } - if (settingsViewModel.showMaterialYouOption) SwitchRow( - title = stringResource(R.string.settings_appearance_materialYou), - description = stringResource(R.string.settings_appearance_materialYou_description), - painter = rememberVectorPainter(Icons.Outlined.Brush), - checked = settingsViewModel.prefs.materialYou + FormSection( + title = stringResource(R.string.settings_appearance_colors), + bottomDivider = false ) { - settingsViewModel.prefs.materialYou = it + SwitchRow( + title = stringResource(R.string.settings_appearance_materialYou), + description = stringResource( + if (supportsMaterialYou) R.string.settings_appearance_materialYou_description + else R.string.settings_appearance_materialYou_unavailable + ), + painter = rememberVectorPainter(Icons.Outlined.Brush), + checked = settingsViewModel.prefs.materialYou, + enabled = supportsMaterialYou + ) { + settingsViewModel.prefs.materialYou = it + } + SwitchRow( + title = stringResource(R.string.settings_appearance_pitchBlack), + description = stringResource(R.string.settings_appearance_pitchBlack_description), + painter = rememberVectorPainter(Icons.Outlined.Contrast), + checked = settingsViewModel.prefs.pitchBlack + ) { + settingsViewModel.prefs.pitchBlack = it + } } } } \ No newline at end of file diff --git a/app/src/main/java/com/aliernfrog/pftool/ui/screen/settings/ExperimentalPage.kt b/app/src/main/java/com/aliernfrog/pftool/ui/screen/settings/ExperimentalPage.kt new file mode 100644 index 00000000..5dc66495 --- /dev/null +++ b/app/src/main/java/com/aliernfrog/pftool/ui/screen/settings/ExperimentalPage.kt @@ -0,0 +1,114 @@ +package com.aliernfrog.pftool.ui.screen.settings + +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.rounded.Done +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import com.aliernfrog.pftool.R +import com.aliernfrog.pftool.SettingsConstant +import com.aliernfrog.pftool.ui.component.form.ButtonRow +import com.aliernfrog.pftool.ui.component.form.FormSection +import com.aliernfrog.pftool.ui.component.form.SwitchRow +import com.aliernfrog.pftool.ui.theme.AppComponentShape +import com.aliernfrog.pftool.ui.viewmodel.MainViewModel +import com.aliernfrog.pftool.util.staticutil.GeneralUtil +import kotlinx.coroutines.launch +import org.koin.androidx.compose.koinViewModel + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun ExperimentalPage( + mainViewModel: MainViewModel = koinViewModel(), + onNavigateBackRequest: () -> Unit +) { + val context = LocalContext.current + val scope = rememberCoroutineScope() + + SettingsPageContainer( + title = stringResource(R.string.settings_experimental), + onNavigateBackRequest = onNavigateBackRequest + ) { + SwitchRow( + title = stringResource(R.string.settings_experimental), + description = stringResource(R.string.settings_experimental_description), + checked = mainViewModel.prefs.experimentalOptionsEnabled, + shape = AppComponentShape, + containerColor = MaterialTheme.colorScheme.primaryContainer, + contentColor = MaterialTheme.colorScheme.onPrimaryContainer, + modifier = Modifier.padding(16.dp) + ) { + mainViewModel.prefs.experimentalOptionsEnabled = it + } + + FormSection(title = "Updates") { + ButtonRow( + title = "Check updates (ignore version)" + ) { + scope.launch { + mainViewModel.checkUpdates(ignoreVersion = true) + } + } + ButtonRow( + title = "Show update toast" + ) { + mainViewModel.showUpdateToast() + } + ButtonRow( + title = "Show update dialog" + ) { + scope.launch { + mainViewModel.updateSheetState.show() + } + } + } + + FormSection(title = "Prefs", bottomDivider = false) { + SwitchRow( + title = "Show map name field guide", + checked = mainViewModel.prefs.showMapNameFieldGuide, + onCheckedChange = { + mainViewModel.prefs.showMapNameFieldGuide = it + } + ) + + SettingsConstant.experimentalPrefOptions.forEach { prefEdit -> + OutlinedTextField( + value = prefEdit.getValue(mainViewModel.prefs), + onValueChange = { + prefEdit.setValue(it, mainViewModel.prefs) + }, + label = { + Text(stringResource(prefEdit.labelResourceId)) + }, + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp, vertical = 8.dp) + ) + } + + ButtonRow( + title = "Reset experimental prefs", + contentColor = MaterialTheme.colorScheme.error + ) { + SettingsConstant.experimentalPrefOptions.forEach { + it.setValue(it.default, mainViewModel.prefs) + } + mainViewModel.topToastState.showAndroidToast( + text = "Restored default values for experimental prefs", + icon = Icons.Rounded.Done + ) + GeneralUtil.restartApp(context) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/aliernfrog/pftool/ui/screen/settings/LanguagePage.kt b/app/src/main/java/com/aliernfrog/pftool/ui/screen/settings/LanguagePage.kt index 5ce4f7f2..059b3328 100644 --- a/app/src/main/java/com/aliernfrog/pftool/ui/screen/settings/LanguagePage.kt +++ b/app/src/main/java/com/aliernfrog/pftool/ui/screen/settings/LanguagePage.kt @@ -10,7 +10,6 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.CheckCircle import androidx.compose.material.icons.filled.Handshake import androidx.compose.material.icons.filled.PhoneAndroid import androidx.compose.material.icons.filled.Translate @@ -18,6 +17,7 @@ import androidx.compose.material3.Card import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.RadioButton import androidx.compose.material3.Text import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable @@ -66,12 +66,12 @@ fun LanguagePage( title = title, description = description, painter = painter, - trailingComponent = if (selected) { { - Icon( - painter = rememberVectorPainter(Icons.Default.CheckCircle), - contentDescription = stringResource(R.string.settings_language_selected) + trailingComponent = { + RadioButton( + selected = selected, + onClick = onClick ) - } } else null, + }, onClick = onClick ) } diff --git a/app/src/main/java/com/aliernfrog/pftool/ui/screen/settings/SettingsScreen.kt b/app/src/main/java/com/aliernfrog/pftool/ui/screen/settings/SettingsScreen.kt index 955fb904..2ce598ee 100644 --- a/app/src/main/java/com/aliernfrog/pftool/ui/screen/settings/SettingsScreen.kt +++ b/app/src/main/java/com/aliernfrog/pftool/ui/screen/settings/SettingsScreen.kt @@ -23,6 +23,7 @@ import androidx.compose.material.icons.outlined.FolderOpen import androidx.compose.material.icons.outlined.Info import androidx.compose.material.icons.outlined.Palette import androidx.compose.material.icons.outlined.PinDrop +import androidx.compose.material.icons.outlined.Science import androidx.compose.material.icons.outlined.Settings import androidx.compose.material.icons.outlined.Translate import androidx.compose.material3.Card @@ -125,7 +126,9 @@ private fun SettingsRootPage( ) SettingsPage.entries - .filter { it != SettingsPage.ROOT } + .filter { + it != SettingsPage.ROOT && !(it == SettingsPage.EXPERIMENTAL && !mainViewModel.prefs.experimentalOptionsEnabled) + } .forEach { page -> ButtonRow( title = stringResource(page.title), @@ -273,6 +276,16 @@ enum class SettingsPage( } ), + EXPERIMENTAL( + id = "experimental", + title = R.string.settings_experimental, + description = R.string.settings_experimental_description, + icon = Icons.Outlined.Science, + content = { onNavigateBackRequest, _ -> + ExperimentalPage(onNavigateBackRequest = onNavigateBackRequest) + } + ), + ABOUT( id = "about", title = R.string.settings_about, diff --git a/app/src/main/java/com/aliernfrog/pftool/ui/theme/Theme.kt b/app/src/main/java/com/aliernfrog/pftool/ui/theme/Theme.kt index 87167709..ec6b5df5 100644 --- a/app/src/main/java/com/aliernfrog/pftool/ui/theme/Theme.kt +++ b/app/src/main/java/com/aliernfrog/pftool/ui/theme/Theme.kt @@ -27,6 +27,7 @@ val supportsMaterialYou = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S fun PFToolTheme( darkTheme: Boolean = isSystemInDarkTheme(), dynamicColors: Boolean = true, + pitchBlack: Boolean = false, content: @Composable () -> Unit ) { val useDynamicColors = supportsMaterialYou && dynamicColors @@ -35,6 +36,9 @@ fun PFToolTheme( useDynamicColors && !darkTheme -> dynamicLightColorScheme(LocalContext.current) darkTheme -> darkColorScheme() else -> lightColorScheme() + }.let { + if (darkTheme && pitchBlack) it.copy(background = Color.Black, surface = Color.Black) + else it } val view = LocalView.current diff --git a/app/src/main/java/com/aliernfrog/pftool/ui/viewmodel/SettingsViewModel.kt b/app/src/main/java/com/aliernfrog/pftool/ui/viewmodel/SettingsViewModel.kt index d4f0dd3b..53ba7076 100644 --- a/app/src/main/java/com/aliernfrog/pftool/ui/viewmodel/SettingsViewModel.kt +++ b/app/src/main/java/com/aliernfrog/pftool/ui/viewmodel/SettingsViewModel.kt @@ -4,12 +4,10 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.rounded.Build import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableIntStateOf -import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.lifecycle.ViewModel import com.aliernfrog.pftool.R import com.aliernfrog.pftool.experimentalSettingsRequiredClicks -import com.aliernfrog.pftool.ui.theme.supportsMaterialYou import com.aliernfrog.pftool.util.manager.PreferenceManager import com.aliernfrog.toptoast.enum.TopToastColor import com.aliernfrog.toptoast.state.TopToastState @@ -18,15 +16,14 @@ class SettingsViewModel( val prefs: PreferenceManager, val topToastState: TopToastState ) : ViewModel() { - var experimentalSettingsShown by mutableStateOf(false) - var showMaterialYouOption by mutableStateOf(supportsMaterialYou) private var aboutClickCount by mutableIntStateOf(0) fun onAboutClick() { - if (aboutClickCount > experimentalSettingsRequiredClicks) return + if (prefs.experimentalOptionsEnabled) return aboutClickCount++ if (aboutClickCount == experimentalSettingsRequiredClicks) { - experimentalSettingsShown = true + aboutClickCount = 0 + prefs.experimentalOptionsEnabled = true topToastState.showToast( text = R.string.settings_experimental_enabled, icon = Icons.Rounded.Build, diff --git a/app/src/main/java/com/aliernfrog/pftool/util/manager/PreferenceManager.kt b/app/src/main/java/com/aliernfrog/pftool/util/manager/PreferenceManager.kt index 7865813f..c3bd10c9 100644 --- a/app/src/main/java/com/aliernfrog/pftool/util/manager/PreferenceManager.kt +++ b/app/src/main/java/com/aliernfrog/pftool/util/manager/PreferenceManager.kt @@ -9,21 +9,23 @@ import com.aliernfrog.pftool.util.manager.base.BasePreferenceManager class PreferenceManager(context: Context) : BasePreferenceManager( prefs = context.getSharedPreferences(ConfigKey.PREF_NAME, Context.MODE_PRIVATE) ) { - // Appearance + // Appearance options var theme by intPreference(ConfigKey.KEY_APP_THEME, Theme.SYSTEM.ordinal) var materialYou by booleanPreference(ConfigKey.KEY_APP_MATERIAL_YOU, true) + var pitchBlack by booleanPreference("pitchBlack", false) - // General + // General options var showChosenMapThumbnail by booleanPreference(ConfigKey.KEY_SHOW_CHOSEN_MAP_THUMBNAIL, true) var showMapThumbnailsInList by booleanPreference(ConfigKey.KEY_SHOW_MAP_THUMBNAILS_LIST, true) var language by stringPreference(ConfigKey.KEY_APP_LANGUAGE, "") // follow system if blank - // Folder configuration + // Storage options var pfMapsDir by stringPreference(ConfigKey.KEY_MAPS_DIR, ConfigKey.RECOMMENDED_MAPS_DIR) var exportedMapsDir by stringPreference(ConfigKey.KEY_EXPORTED_MAPS_DIR, ConfigKey.RECOMMENDED_EXPORTED_MAPS_DIR) var storageAccessType by intPreference("storageAccessType", StorageAccessType.SAF.ordinal) - // Experimental (developer) + // Experimental (developer) options + var experimentalOptionsEnabled by booleanPreference("experimentalOptionsEnabled", false) var showMapNameFieldGuide by booleanPreference("showMapNameFieldGuide", true) var autoCheckUpdates by booleanPreference(ConfigKey.KEY_APP_AUTO_UPDATES, true) var updatesURL by stringPreference(ConfigKey.KEY_APP_UPDATES_URL, ConfigKey.DEFAULT_UPDATES_URL) diff --git a/app/src/main/res/values-pl-rPL/strings.xml b/app/src/main/res/values-pl-rPL/strings.xml index e656c3dd..6d8e2739 100644 --- a/app/src/main/res/values-pl-rPL/strings.xml +++ b/app/src/main/res/values-pl-rPL/strings.xml @@ -85,7 +85,6 @@ Kliknij, aby wyświetlić więcej szczegółów i działań Wygląd Motyw - Preferencje trybu ciemnego Zgodnie z urządzeniem Jasny Ciemny @@ -117,14 +116,7 @@ Ustawienia eksperymentalne Ustawienia eksperymentalne włączone! Te ustawienia nie są przeznaczone do normalnego użytku i mogą zepsuć PF Tool w przypadku niewłaściwego użycia - Pokaż opcję Material You - Pokaż samouczek dla pola nazwy mapy - Sprawdź aktualizacje (ignoruj wersję) - Pokaż toast aktualizacji - Pokaż okno dialogowe aktualizacji Aktualizacje URL - Resetuj eksperymentalne preferencje - Przywrócono domyślne wartości dla preferencji eksperymentalnych Dostępna jest aktualizacja PF Tool! Kliknij, aby uzyskać więcej informacji Brak dostępnych aktualizacji Coś poszło nie tak podczas szukania aktualizacji diff --git a/app/src/main/res/values-tr-rTR/strings.xml b/app/src/main/res/values-tr-rTR/strings.xml index f1e10b3e..4cb25f7a 100644 --- a/app/src/main/res/values-tr-rTR/strings.xml +++ b/app/src/main/res/values-tr-rTR/strings.xml @@ -42,7 +42,7 @@ Dışa aktarılan haritalar klasörü Dışa aktarılan haritaları saklamak istediğiniz klasörü seçmeniz gerekiyor PF Tool eski sürümlerde bu klasörü kullandı, eğer daha önce dışa aktardığınız haritalara erişmek istiyorsanız bu klasörü seçin - Shizuku, kablosuz hata ayıklamayı kullanarak diğer uygulamaların kabul (shell) izinlerini kullanmasını sağlayan bir uygulamadır.\nShizuku modu Ayarlar > Depolama > Depolama erişimi tipi kısmından devre dışı bırakılabilir + Shizuku, kablosuz hata ayıklamayı kullanarak diğer uygulamaların kabuk (shell) izinlerini kullanmasını sağlayan bir uygulamadır.\nShizuku modu Ayarlar > Depolama > Depolama erişimi tipi kısmından devre dışı bırakılabilir Shizuku\'yu yükleyerek başlayın Yükle Shizuku çalışmıyor @@ -111,12 +111,15 @@ Görünüm PF Tool\'un görünümünü özelleştirin Tema - Karanlık mod tercihi - Sistem teması + Sistem Aydınlık Karanlık + Renkler Material You Cihazınızdaki renklere göre bir tema + Sadece Android 12 ve üzerinde kullanılabilir + Zifiri karanlık + Karanlık mod etkinken zifiri karanlık arka plan Harita resimleri Harita resimlerinin ne zaman gösterileceğini ayarlayın Seçilen haritanın resmini göster @@ -163,15 +166,8 @@ Değişiklik günlüğünü görmek için güncellemeleri denetleyin Deneysel ayarlar Deneysel ayarlar açıldı! - Bu ayarlar normal kullanım için değildir ve yanlış kullanıldığında PF Tool\'u bozabilir - Material You seçeneğini göster - Harita isim alanı rehberini göster - Güncellemeleri denetle (sürümü yoksay) - Güncelleme mesajını göster - Güncelleme diyaloğunu göster + Normal kullanım için değildir, yanlış kullanıldığında uygulamayı bozabilir Güncellemeler için URL - Deneysel tercihleri sıfırla - Deneysel tercihlerin varsayılan değerleri geri yüklendi PF Tool güncellemesi mevcut! Daha fazla detay için tıklayın Güncelleme yok Güncellemeleri denetlerken bir şeyler ters gitti diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index f1c8756e..4964c518 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -85,7 +85,6 @@ 点击查看更多详细信息和操作 外观 主题 - 暗色模式选项 跟随系统 亮色 深色 @@ -117,14 +116,7 @@ 实验性功能设置 已启用实验性设置! 这些设置不适用于常规使用,如果被滥用可能会导致 PF Tool 故障。 - 显示“Material You”选项 - 显示地图名称字段指南 - 检查更新 (忽略版本) - 显示更新提示 - 显示更新提示 更新网址 - 重置实验性偏好设置 - 恢复实验性选项的默认值 PF 工具更新可用!点击获取更多详细信息 没有可用的更新 检查更新时出错。 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d3406ff7..3e770eca 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -111,12 +111,15 @@ Appearance Customize the look of PF Tool Theme - Dark mode preference - Follow system + System Light Dark + Colors Material You Theme based on colors of your device + Only available on Android 12 and above + Pitch black + Pitch black background when dark mode is enabled Map thumbnails Configure when map thumbnails will be shown Show thumbnail of selected map @@ -163,15 +166,8 @@ Check updates to view changelog Experimental settings Experimental settings enabled! - These settings are not intended for normal usage and they might break PF Tool when misused - Show Material You option - Show map name field guide - Check updates (ignore version) - Show update toast - Show update dialog + Not intended for normal usage, might break the app when misused Updates URL - Reset experimental prefs - Restored defaults values for experimental prefs PF Tool update available! Click for more details No updates available Something went wrong while checking for updates