diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 48d16183..63e45933 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -50,16 +50,6 @@
android:name=".ui.map.MapActivity"
android:exported="true"
android:excludeFromRecents="true" />
-
-
+ }.onEach { (section, instance) ->
+ instance.enumSection = section
instance.manager = context
instance.navController = navController
} }
NavHost(navController, startDestination = startDestination.route, Modifier.padding(innerPadding)) {
- sections.forEach { (section, instance) ->
- composable(section.route) {
- instance.Content()
- }
+ sections.forEach { (_, instance) ->
+ instance.build(this)
}
}
}
diff --git a/app/src/main/kotlin/me/rhunk/snapenhance/manager/Section.kt b/app/src/main/kotlin/me/rhunk/snapenhance/manager/Section.kt
index 8cf1d226..ab9d338c 100644
--- a/app/src/main/kotlin/me/rhunk/snapenhance/manager/Section.kt
+++ b/app/src/main/kotlin/me/rhunk/snapenhance/manager/Section.kt
@@ -9,10 +9,12 @@ import androidx.compose.material.icons.filled.Stars
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.navigation.NavController
+import androidx.navigation.NavGraphBuilder
+import androidx.navigation.compose.composable
import me.rhunk.snapenhance.manager.data.ManagerContext
-import me.rhunk.snapenhance.manager.sections.FeaturesSection
import me.rhunk.snapenhance.manager.sections.HomeSection
import me.rhunk.snapenhance.manager.sections.NotImplemented
+import me.rhunk.snapenhance.manager.sections.features.FeaturesSection
import kotlin.reflect.KClass
enum class EnumSection(
@@ -59,9 +61,16 @@ enum class EnumSection(
open class Section {
+ lateinit var enumSection: EnumSection
lateinit var manager: ManagerContext
lateinit var navController: NavController
@Composable
open fun Content() { NotImplemented() }
+
+ open fun build(navGraphBuilder: NavGraphBuilder) {
+ navGraphBuilder.composable(enumSection.route) {
+ Content()
+ }
+ }
}
\ No newline at end of file
diff --git a/app/src/main/kotlin/me/rhunk/snapenhance/manager/data/ManagerContext.kt b/app/src/main/kotlin/me/rhunk/snapenhance/manager/data/ManagerContext.kt
index ab6863e2..c8643a7c 100644
--- a/app/src/main/kotlin/me/rhunk/snapenhance/manager/data/ManagerContext.kt
+++ b/app/src/main/kotlin/me/rhunk/snapenhance/manager/data/ManagerContext.kt
@@ -1,7 +1,6 @@
package me.rhunk.snapenhance.manager.data
import android.content.Context
-import me.rhunk.snapenhance.bridge.wrapper.ConfigWrapper
import me.rhunk.snapenhance.bridge.wrapper.MappingsWrapper
import me.rhunk.snapenhance.bridge.wrapper.TranslationWrapper
import me.rhunk.snapenhance.core.config.ModConfig
diff --git a/app/src/main/kotlin/me/rhunk/snapenhance/manager/sections/FeaturesSection.kt b/app/src/main/kotlin/me/rhunk/snapenhance/manager/sections/FeaturesSection.kt
deleted file mode 100644
index b0c60b7b..00000000
--- a/app/src/main/kotlin/me/rhunk/snapenhance/manager/sections/FeaturesSection.kt
+++ /dev/null
@@ -1,235 +0,0 @@
-package me.rhunk.snapenhance.manager.sections
-
-import androidx.compose.foundation.clickable
-import androidx.compose.foundation.layout.Arrangement
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.fillMaxHeight
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.widthIn
-import androidx.compose.foundation.layout.wrapContentWidth
-import androidx.compose.foundation.lazy.LazyColumn
-import androidx.compose.foundation.lazy.items
-import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.material.MaterialTheme
-import androidx.compose.material.SnackbarHost
-import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.filled.OpenInNew
-import androidx.compose.material.icons.rounded.Save
-import androidx.compose.material.rememberScaffoldState
-import androidx.compose.material3.Card
-import androidx.compose.material3.FilledIconButton
-import androidx.compose.material3.FloatingActionButton
-import androidx.compose.material3.Icon
-import androidx.compose.material3.IconButton
-import androidx.compose.material3.Scaffold
-import androidx.compose.material3.Switch
-import androidx.compose.material3.Text
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
-import androidx.compose.runtime.rememberCoroutineScope
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.text.font.FontWeight
-import androidx.compose.ui.text.style.TextOverflow
-import androidx.compose.ui.tooling.preview.Preview
-import androidx.compose.ui.unit.dp
-import androidx.compose.ui.unit.sp
-import androidx.compose.ui.window.Dialog
-import androidx.compose.ui.window.DialogProperties
-import kotlinx.coroutines.launch
-import me.rhunk.snapenhance.Logger
-import me.rhunk.snapenhance.config.ConfigProperty
-import me.rhunk.snapenhance.config.impl.ConfigIntegerValue
-import me.rhunk.snapenhance.config.impl.ConfigStateListValue
-import me.rhunk.snapenhance.config.impl.ConfigStateSelection
-import me.rhunk.snapenhance.config.impl.ConfigStateValue
-import me.rhunk.snapenhance.config.impl.ConfigStringValue
-import me.rhunk.snapenhance.manager.Dialogs
-import me.rhunk.snapenhance.manager.Section
-
-typealias ClickCallback = (Boolean) -> Unit
-typealias RegisterClickCallback = (ClickCallback) -> ClickCallback
-
-class FeaturesSection : Section() {
- private val dialogs by lazy { Dialogs(manager) }
-
- @Composable
- private fun PropertyAction(item: ConfigProperty, registerClickCallback: RegisterClickCallback) {
- val showDialog = remember { mutableStateOf(false) }
- val dialogComposable = remember { mutableStateOf<@Composable () -> Unit>({})}
-
- fun registerDialogOnClickCallback() = registerClickCallback {
- showDialog.value = true
- }
-
- if (showDialog.value) {
- Dialog(onDismissRequest = { showDialog.value = false }, properties = DialogProperties()) {
- dialogComposable.value()
- }
- }
-
- when (val container = remember { item.valueContainer }) {
- is ConfigStateValue -> {
- val state = remember { mutableStateOf(container.value()) }
- Switch(
- checked = state.value,
- onCheckedChange = registerClickCallback {
- state.value = state.value.not()
- container.writeFrom(state.value.toString())
- }
- )
- }
-
- is ConfigStateSelection -> {
- registerDialogOnClickCallback()
- dialogComposable.value = {
- dialogs.StateSelectionDialog(item)
- }
- Text(
- overflow = TextOverflow.Ellipsis,
- maxLines = 1,
- modifier = Modifier.widthIn(0.dp, 120.dp),
- text = if (item.disableValueLocalization) container.value() else {
- manager.translation.propertyOption(item, container.value())
- },
- )
- }
-
- is ConfigStateListValue, is ConfigStringValue, is ConfigIntegerValue -> {
- dialogComposable.value = {
- when (container) {
- is ConfigStateListValue -> {
- dialogs.StateListDialog(item)
- }
- is ConfigStringValue, is ConfigIntegerValue -> {
- dialogs.KeyboardInputDialog(item) { showDialog.value = false }
- }
- }
- }
-
- registerDialogOnClickCallback().let { { it.invoke(true) } }.also {
- if (container is ConfigIntegerValue) {
- FilledIconButton(onClick = it) {
- Text(text = container.value().toString(), modifier = Modifier.wrapContentWidth(), overflow = TextOverflow.Ellipsis)
- }
- } else {
- IconButton(onClick = it) {
- Icon(Icons.Filled.OpenInNew, contentDescription = null)
- }
- }
- }
- }
- }
- }
-
- @Composable
- private fun PropertyCard(item: ConfigProperty) {
- val clickCallback = remember { mutableStateOf(null) }
- Card(
- modifier = Modifier
- .fillMaxWidth()
- .clickable {
- clickCallback.value?.invoke(true)
- }
- .padding(start = 10.dp, end = 10.dp, top = 5.dp, bottom = 5.dp)
- ) {
- Row(
- modifier = Modifier
- .fillMaxSize()
- .padding(all = 4.dp),
- horizontalArrangement = Arrangement.SpaceBetween
- ) {
- Column(
- modifier = Modifier
- .align(Alignment.CenterVertically)
- .weight(1f, fill = true)
- .padding(all = 10.dp)
- ) {
- Text(text = manager.translation.propertyName(item), fontSize = 16.sp, fontWeight = FontWeight.Bold)
- Text(
- text = manager.translation.propertyDescription(item),
- fontSize = 12.sp,
- lineHeight = 15.sp
- )
- }
-
- Column(
- modifier = Modifier
- .align(Alignment.CenterVertically)
- .padding(all = 10.dp)
- ) {
- PropertyAction(item, registerClickCallback = { callback ->
- clickCallback.value = callback
- callback
- })
- }
- }
- }
- }
-
- @Composable
- private fun PropertyContainer() {
- val properties = remember {
- val items by manager.config
- items.properties.map { it.key to it.value }
- }
-
- LazyColumn(
- modifier = Modifier
- .fillMaxHeight(),
- verticalArrangement = Arrangement.Center
- ) {
- items(properties) { (key, value) ->
- // Logger.debug("key: $key, value: $value")
- }
- }
- }
-
-
- @Composable
- @Preview
- override fun Content() {
- val scope = rememberCoroutineScope()
- val scaffoldState = rememberScaffoldState()
- Scaffold(
- snackbarHost = { SnackbarHost(scaffoldState.snackbarHostState) },
- floatingActionButton = {
- FloatingActionButton(
- onClick = {
- //manager.config.writeConfig()
- scope.launch {
- scaffoldState.snackbarHostState.showSnackbar("Saved")
- }
- },
- containerColor = MaterialTheme.colors.primary,
- contentColor = MaterialTheme.colors.onPrimary,
- shape = RoundedCornerShape(16.dp),
- ) {
- Icon(
- imageVector = Icons.Rounded.Save,
- contentDescription = null
- )
- }
- },
- modifier = Modifier.fillMaxSize(),
- content = { innerPadding ->
- Column(
- modifier = Modifier
- .fillMaxSize()
- .padding(innerPadding)
- ) {
- Text(
- text = "Features",
- modifier = Modifier.padding(all = 10.dp),
- fontSize = 20.sp
- )
- PropertyContainer()
- }
- }
- )
- }
-}
\ No newline at end of file
diff --git a/app/src/main/kotlin/me/rhunk/snapenhance/manager/sections/features/CallbackAlias.kt b/app/src/main/kotlin/me/rhunk/snapenhance/manager/sections/features/CallbackAlias.kt
new file mode 100644
index 00000000..9e93b545
--- /dev/null
+++ b/app/src/main/kotlin/me/rhunk/snapenhance/manager/sections/features/CallbackAlias.kt
@@ -0,0 +1,4 @@
+package me.rhunk.snapenhance.manager.sections.features
+
+typealias ClickCallback = (Boolean) -> Unit
+typealias RegisterClickCallback = (ClickCallback) -> ClickCallback
\ No newline at end of file
diff --git a/app/src/main/kotlin/me/rhunk/snapenhance/manager/Dialogs.kt b/app/src/main/kotlin/me/rhunk/snapenhance/manager/sections/features/Dialogs.kt
similarity index 71%
rename from app/src/main/kotlin/me/rhunk/snapenhance/manager/Dialogs.kt
rename to app/src/main/kotlin/me/rhunk/snapenhance/manager/sections/features/Dialogs.kt
index 586c9b66..5e07232e 100644
--- a/app/src/main/kotlin/me/rhunk/snapenhance/manager/Dialogs.kt
+++ b/app/src/main/kotlin/me/rhunk/snapenhance/manager/sections/features/Dialogs.kt
@@ -1,4 +1,4 @@
-package me.rhunk.snapenhance.manager
+package me.rhunk.snapenhance.manager.sections.features
import androidx.compose.foundation.ScrollState
import androidx.compose.foundation.clickable
@@ -29,16 +29,11 @@ import androidx.compose.ui.text.TextRange
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.unit.dp
-import me.rhunk.snapenhance.config.ConfigProperty
-import me.rhunk.snapenhance.config.impl.ConfigIntegerValue
-import me.rhunk.snapenhance.config.impl.ConfigStateListValue
-import me.rhunk.snapenhance.config.impl.ConfigStateSelection
-import me.rhunk.snapenhance.manager.data.ManagerContext
+import me.rhunk.snapenhance.core.config.DataProcessors
+import me.rhunk.snapenhance.core.config.PropertyPair
-class Dialogs(
- private val context: ManagerContext
-) {
+class Dialogs {
@Composable
fun DefaultDialogCard(content: @Composable ColumnScope.() -> Unit) {
Card(
@@ -65,17 +60,25 @@ class Dialogs(
}
@Composable
- fun StateSelectionDialog(config: ConfigProperty) {
- assert(config.valueContainer is ConfigStateSelection)
- val keys = (config.valueContainer as ConfigStateSelection).keys()
- val selectedValue = remember {
- mutableStateOf(config.valueContainer.value())
+ @Suppress("UNCHECKED_CAST")
+ fun UniqueSelectionDialog(property: PropertyPair<*>) {
+ val keys = (property.value.defaultValues as List).toMutableList().apply {
+ add(0, "disabled")
}
+
+ val selectedValue = remember {
+ mutableStateOf(property.value.getNullable()?.toString() ?: "disabled")
+ }
+
DefaultDialogCard {
- keys.forEach { item ->
+ keys.forEachIndexed { index, item ->
fun select() {
selectedValue.value = item
- config.valueContainer.writeFrom(item)
+ property.value.setAny(if (index == 0) {
+ null
+ } else {
+ item
+ })
}
Row(
@@ -83,9 +86,7 @@ class Dialogs(
verticalAlignment = Alignment.CenterVertically
) {
DefaultEntryText(
- text = if (config.disableValueLocalization)
- item
- else context.translation.propertyOption(config, item),
+ text = item,
modifier = Modifier.weight(1f)
)
RadioButton(
@@ -98,12 +99,12 @@ class Dialogs(
}
@Composable
- fun KeyboardInputDialog(config: ConfigProperty, dismiss: () -> Unit = {}) {
+ fun KeyboardInputDialog(property: PropertyPair<*>, dismiss: () -> Unit = {}) {
val focusRequester = remember { FocusRequester() }
DefaultDialogCard {
val fieldValue = remember {
- mutableStateOf(config.valueContainer.read().let {
+ mutableStateOf(property.value.get().toString().let {
TextFieldValue(
text = it,
selection = TextRange(it.length)
@@ -123,8 +124,8 @@ class Dialogs(
onValueChange = {
fieldValue.value = it
},
- keyboardOptions = when (config.valueContainer) {
- is ConfigIntegerValue -> {
+ keyboardOptions = when (property.key.dataType.type) {
+ DataProcessors.Type.INTEGER -> {
KeyboardOptions(keyboardType = KeyboardType.Number)
}
else -> {
@@ -142,7 +143,15 @@ class Dialogs(
Text(text = "Cancel")
}
Button(onClick = {
- config.valueContainer.writeFrom(fieldValue.value.text)
+ if (property.key.dataType.type == DataProcessors.Type.INTEGER) {
+ runCatching {
+ property.value.setAny(fieldValue.value.text.toInt())
+ }.onFailure {
+ property.value.setAny(0)
+ }
+ } else {
+ property.value.setAny(fieldValue.value.text)
+ }
dismiss()
}) {
Text(text = "Ok")
@@ -152,18 +161,23 @@ class Dialogs(
}
@Composable
- fun StateListDialog(config: ConfigProperty) {
- assert(config.valueContainer is ConfigStateListValue)
- val stateList = (config.valueContainer as ConfigStateListValue).value()
+ @Suppress("UNCHECKED_CAST")
+ fun MultipleSelectionDialog(property: PropertyPair<*>) {
+ val defaultItems = property.value.defaultValues as List
+ val toggledStates = property.value.get() as MutableList
DefaultDialogCard {
- stateList.keys.forEach { key ->
+ defaultItems.forEach { key ->
val state = remember {
- mutableStateOf(stateList[key] ?: false)
+ mutableStateOf(toggledStates.contains(key))
}
fun toggle(value: Boolean? = null) {
state.value = value ?: !state.value
- stateList[key] = state.value
+ if (state.value) {
+ toggledStates.add(key)
+ } else {
+ toggledStates.remove(key)
+ }
}
Row(
@@ -171,9 +185,7 @@ class Dialogs(
verticalAlignment = Alignment.CenterVertically
) {
DefaultEntryText(
- text = if (config.disableValueLocalization)
- key
- else context.translation.propertyOption(config, key),
+ text = key,
modifier = Modifier
.weight(1f)
)
diff --git a/app/src/main/kotlin/me/rhunk/snapenhance/manager/sections/features/FeaturesSection.kt b/app/src/main/kotlin/me/rhunk/snapenhance/manager/sections/features/FeaturesSection.kt
new file mode 100644
index 00000000..75629241
--- /dev/null
+++ b/app/src/main/kotlin/me/rhunk/snapenhance/manager/sections/features/FeaturesSection.kt
@@ -0,0 +1,293 @@
+package me.rhunk.snapenhance.manager.sections.features
+
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxHeight
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.widthIn
+import androidx.compose.foundation.layout.wrapContentWidth
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.lazy.items
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.MaterialTheme
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.ArrowBack
+import androidx.compose.material.icons.filled.OpenInNew
+import androidx.compose.material.icons.rounded.Save
+import androidx.compose.material3.Card
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.FilledIconButton
+import androidx.compose.material3.FloatingActionButton
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
+import androidx.compose.material3.Scaffold
+import androidx.compose.material3.SnackbarHost
+import androidx.compose.material3.Switch
+import androidx.compose.material3.Text
+import androidx.compose.material3.TopAppBar
+import androidx.compose.material3.rememberBottomSheetScaffoldState
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import androidx.compose.ui.window.Dialog
+import androidx.compose.ui.window.DialogProperties
+import androidx.navigation.NavGraphBuilder
+import androidx.navigation.compose.composable
+import androidx.navigation.navigation
+import kotlinx.coroutines.launch
+import me.rhunk.snapenhance.core.config.ConfigContainer
+import me.rhunk.snapenhance.core.config.DataProcessors
+import me.rhunk.snapenhance.core.config.PropertyPair
+import me.rhunk.snapenhance.manager.Section
+
+class FeaturesSection : Section() {
+ private val dialogs by lazy { Dialogs() }
+
+ companion object {
+ private const val MAIN_ROUTE = "root"
+ }
+
+ @Composable
+ private fun PropertyAction(property: PropertyPair<*>, registerClickCallback: RegisterClickCallback) {
+ val showDialog = remember { mutableStateOf(false) }
+ val dialogComposable = remember { mutableStateOf<@Composable () -> Unit>({}) }
+
+ fun registerDialogOnClickCallback() = registerClickCallback {
+ showDialog.value = true
+ }
+
+ if (showDialog.value) {
+ Dialog(
+ onDismissRequest = { showDialog.value = false },
+ properties = DialogProperties()
+ ) {
+ dialogComposable.value()
+ }
+ }
+
+ val propertyValue = property.value
+
+ when (val dataType = remember { property.key.dataType.type }) {
+ DataProcessors.Type.BOOLEAN -> {
+ val state = remember { mutableStateOf(propertyValue.get() as Boolean) }
+ Switch(
+ checked = state.value,
+ onCheckedChange = registerClickCallback {
+ state.value = state.value.not()
+ propertyValue.setAny(state.value)
+ }
+ )
+ }
+
+ DataProcessors.Type.STRING_UNIQUE_SELECTION -> {
+ registerDialogOnClickCallback()
+
+ dialogComposable.value = {
+ dialogs.UniqueSelectionDialog(property)
+ }
+
+ Text(
+ overflow = TextOverflow.Ellipsis,
+ maxLines = 1,
+ modifier = Modifier.widthIn(0.dp, 120.dp),
+ text = (propertyValue.getNullable() as? String) ?: "Disabled",
+ )
+ }
+
+ DataProcessors.Type.STRING_MULTIPLE_SELECTION, DataProcessors.Type.STRING, DataProcessors.Type.INTEGER -> {
+ dialogComposable.value = {
+ when (dataType) {
+ DataProcessors.Type.STRING_MULTIPLE_SELECTION -> {
+ dialogs.MultipleSelectionDialog(property)
+ }
+ DataProcessors.Type.STRING, DataProcessors.Type.INTEGER -> {
+ dialogs.KeyboardInputDialog(property) { showDialog.value = false }
+ }
+ else -> {}
+ }
+ }
+
+ registerDialogOnClickCallback().let { { it.invoke(true) } }.also {
+ if (dataType == DataProcessors.Type.INTEGER) {
+ FilledIconButton(onClick = it) {
+ Text(
+ text = propertyValue.get().toString(),
+ modifier = Modifier.wrapContentWidth(),
+ overflow = TextOverflow.Ellipsis
+ )
+ }
+ } else {
+ IconButton(onClick = it) {
+ Icon(Icons.Filled.OpenInNew, contentDescription = null)
+ }
+ }
+ }
+ }
+ else -> {}
+ }
+
+ }
+
+ @Composable
+ private fun PropertyCard(property: PropertyPair<*>) {
+ val clickCallback = remember { mutableStateOf(null) }
+ Card(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(start = 10.dp, end = 10.dp, top = 5.dp, bottom = 5.dp)
+ ) {
+ Row(
+ modifier = Modifier
+ .fillMaxSize()
+ .clickable {
+ clickCallback.value?.invoke(true)
+ }
+ .padding(all = 4.dp),
+ horizontalArrangement = Arrangement.SpaceBetween
+ ) {
+ Column(
+ modifier = Modifier
+ .align(Alignment.CenterVertically)
+ .weight(1f, fill = true)
+ .padding(all = 10.dp)
+ ) {
+ Text(
+ text = property.name,
+ fontSize = 16.sp,
+ fontWeight = FontWeight.Bold
+ )
+ Text(
+ text = property.name,
+ fontSize = 12.sp,
+ lineHeight = 15.sp
+ )
+ }
+
+ when (property.key.dataType.type) {
+ DataProcessors.Type.CONTAINER -> {
+ clickCallback.value = {
+ navController.navigate("container/${property.name}")
+ }
+ }
+ else -> {
+ Column(
+ modifier = Modifier
+ .align(Alignment.CenterVertically)
+ .padding(all = 10.dp)
+ ) {
+ PropertyAction(property, registerClickCallback = { callback ->
+ clickCallback.value = callback
+ callback
+ })
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+ @OptIn(ExperimentalMaterial3Api::class)
+ @Composable
+ private fun Container(
+ containerName: String,
+ configContainer: ConfigContainer
+ ) {
+ val properties = remember {
+ configContainer.properties.map { PropertyPair(it.key, it.value) }
+ }
+
+ val scope = rememberCoroutineScope()
+ val scaffoldState = rememberBottomSheetScaffoldState()
+ Scaffold(
+ snackbarHost = { SnackbarHost(scaffoldState.snackbarHostState) },
+ modifier = Modifier.fillMaxSize(),
+ topBar = {
+ TopAppBar(
+ title = {
+ Text(text = containerName, textAlign = TextAlign.Center)
+ },
+ navigationIcon = {
+ if (navController.currentBackStackEntry?.destination?.route != MAIN_ROUTE) {
+ IconButton(onClick = { navController.popBackStack() }) {
+ Icon(Icons.Filled.ArrowBack, contentDescription = null)
+ }
+ }
+ }
+ )
+ },
+ floatingActionButton = {
+ FloatingActionButton(
+ onClick = {
+ manager.config.writeConfig()
+ scope.launch {
+ scaffoldState.snackbarHostState.showSnackbar("Saved")
+ }
+ },
+ modifier = Modifier.padding(25.dp),
+ containerColor = MaterialTheme.colors.primary,
+ contentColor = MaterialTheme.colors.onPrimary,
+ shape = RoundedCornerShape(16.dp),
+ ) {
+ Icon(
+ imageVector = Icons.Rounded.Save,
+ contentDescription = null
+ )
+ }
+ },
+ content = { innerPadding ->
+ LazyColumn(
+ modifier = Modifier.fillMaxHeight().padding(innerPadding),
+ verticalArrangement = Arrangement.Center
+ ) {
+ items(properties) {
+ PropertyCard(it)
+ }
+ }
+ }
+ )
+
+ }
+
+ override fun build(navGraphBuilder: NavGraphBuilder) {
+ val allContainers by lazy {
+ val containers = mutableMapOf()
+ fun queryContainerRecursive(container: ConfigContainer) {
+ container.properties.forEach {
+ if (it.key.dataType.type == DataProcessors.Type.CONTAINER) {
+ containers[it.key.name] = it.value.get() as ConfigContainer
+ queryContainerRecursive(it.value.get() as ConfigContainer)
+ }
+ }
+ }
+ queryContainerRecursive(manager.config.root)
+ containers
+ }
+
+ navGraphBuilder.navigation(route = "features", startDestination = MAIN_ROUTE) {
+ composable(MAIN_ROUTE) {
+ Container(MAIN_ROUTE, manager.config.root)
+ }
+
+ composable("container/{name}") { backStackEntry ->
+ backStackEntry.arguments?.getString("name")?.let { containerName ->
+ allContainers[containerName]?.let {
+ Container(containerName, it)
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/me/rhunk/snapenhance/manager/util/SaveFolderChecker.kt b/app/src/main/kotlin/me/rhunk/snapenhance/manager/util/SaveFolderChecker.kt
index 757b903b..47601295 100644
--- a/app/src/main/kotlin/me/rhunk/snapenhance/manager/util/SaveFolderChecker.kt
+++ b/app/src/main/kotlin/me/rhunk/snapenhance/manager/util/SaveFolderChecker.kt
@@ -6,7 +6,6 @@ import android.content.Intent
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.result.contract.ActivityResultContracts
-import me.rhunk.snapenhance.Logger
import me.rhunk.snapenhance.core.config.PropertyValue
import kotlin.system.exitProcess
diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/ModContext.kt b/core/src/main/kotlin/me/rhunk/snapenhance/ModContext.kt
index 9ece2f56..7fa0f779 100644
--- a/core/src/main/kotlin/me/rhunk/snapenhance/ModContext.kt
+++ b/core/src/main/kotlin/me/rhunk/snapenhance/ModContext.kt
@@ -14,7 +14,6 @@ import kotlinx.coroutines.asCoroutineDispatcher
import me.rhunk.snapenhance.bridge.BridgeClient
import me.rhunk.snapenhance.bridge.wrapper.TranslationWrapper
import me.rhunk.snapenhance.core.config.ModConfig
-import me.rhunk.snapenhance.core.config.impl.RootConfig
import me.rhunk.snapenhance.data.MessageSender
import me.rhunk.snapenhance.database.DatabaseAccess
import me.rhunk.snapenhance.features.Feature
diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/SharedContext.kt b/core/src/main/kotlin/me/rhunk/snapenhance/SharedContext.kt
index 2b1904ac..77d3a289 100644
--- a/core/src/main/kotlin/me/rhunk/snapenhance/SharedContext.kt
+++ b/core/src/main/kotlin/me/rhunk/snapenhance/SharedContext.kt
@@ -7,7 +7,6 @@ import android.content.Intent
import android.os.Build
import android.os.Environment
import android.provider.Settings
-import me.rhunk.snapenhance.bridge.wrapper.ConfigWrapper
import me.rhunk.snapenhance.bridge.wrapper.TranslationWrapper
import me.rhunk.snapenhance.download.DownloadTaskManager
import kotlin.system.exitProcess
@@ -18,7 +17,6 @@ import kotlin.system.exitProcess
object SharedContext {
lateinit var downloadTaskManager: DownloadTaskManager
lateinit var translation: TranslationWrapper
- lateinit var config: ConfigWrapper
private fun askForStoragePermission(context: Context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
@@ -76,10 +74,6 @@ object SharedContext {
loadFromContext(context)
}
}
- if (!this::config.isInitialized) {
- config = ConfigWrapper().apply { loadFromContext(context) }
- }
-
//askForPermissions(context)
}
}
\ No newline at end of file
diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/action/AbstractAction.kt b/core/src/main/kotlin/me/rhunk/snapenhance/action/AbstractAction.kt
index 4bc21cc0..6026691c 100644
--- a/core/src/main/kotlin/me/rhunk/snapenhance/action/AbstractAction.kt
+++ b/core/src/main/kotlin/me/rhunk/snapenhance/action/AbstractAction.kt
@@ -1,12 +1,10 @@
package me.rhunk.snapenhance.action
import me.rhunk.snapenhance.ModContext
-import me.rhunk.snapenhance.config.ConfigProperty
import java.io.File
abstract class AbstractAction(
- val nameKey: String,
- val dependsOnProperty: ConfigProperty? = null,
+ val nameKey: String
) {
lateinit var context: ModContext
diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/action/impl/CheckForUpdates.kt b/core/src/main/kotlin/me/rhunk/snapenhance/action/impl/CheckForUpdates.kt
index c142d1fa..3a8e2094 100644
--- a/core/src/main/kotlin/me/rhunk/snapenhance/action/impl/CheckForUpdates.kt
+++ b/core/src/main/kotlin/me/rhunk/snapenhance/action/impl/CheckForUpdates.kt
@@ -1,10 +1,9 @@
package me.rhunk.snapenhance.action.impl
import me.rhunk.snapenhance.action.AbstractAction
-import me.rhunk.snapenhance.config.ConfigProperty
import me.rhunk.snapenhance.features.impl.AutoUpdater
-class CheckForUpdates : AbstractAction("action.check_for_updates", dependsOnProperty = ConfigProperty.AUTO_UPDATER) {
+class CheckForUpdates : AbstractAction("action.check_for_updates") {
override fun run() {
context.executeAsync {
runCatching {
diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/action/impl/OpenMap.kt b/core/src/main/kotlin/me/rhunk/snapenhance/action/impl/OpenMap.kt
index bb5854a0..64180203 100644
--- a/core/src/main/kotlin/me/rhunk/snapenhance/action/impl/OpenMap.kt
+++ b/core/src/main/kotlin/me/rhunk/snapenhance/action/impl/OpenMap.kt
@@ -3,11 +3,10 @@ package me.rhunk.snapenhance.action.impl
import android.content.Intent
import android.os.Bundle
import me.rhunk.snapenhance.action.AbstractAction
-import me.rhunk.snapenhance.config.ConfigProperty
import me.rhunk.snapenhance.core.BuildConfig
import me.rhunk.snapenhance.ui.map.MapActivity
-class OpenMap: AbstractAction("action.open_map", dependsOnProperty = ConfigProperty.LOCATION_SPOOF) {
+class OpenMap: AbstractAction("action.open_map") {
override fun run() {
context.runOnUiThread {
val mapActivityIntent = Intent()
diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/bridge/BridgeClient.kt b/core/src/main/kotlin/me/rhunk/snapenhance/bridge/BridgeClient.kt
index 6c9dd3f0..b3819ce3 100644
--- a/core/src/main/kotlin/me/rhunk/snapenhance/bridge/BridgeClient.kt
+++ b/core/src/main/kotlin/me/rhunk/snapenhance/bridge/BridgeClient.kt
@@ -10,10 +10,10 @@ import android.os.Handler
import android.os.HandlerThread
import android.os.IBinder
import de.robv.android.xposed.XposedHelpers
-import me.rhunk.snapenhance.core.BuildConfig
import me.rhunk.snapenhance.Logger.xposedLog
import me.rhunk.snapenhance.ModContext
import me.rhunk.snapenhance.bridge.types.BridgeFileType
+import me.rhunk.snapenhance.core.BuildConfig
import me.rhunk.snapenhance.data.LocalePair
import java.util.concurrent.CompletableFuture
import java.util.concurrent.Executors
diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/bridge/wrapper/ConfigWrapper.kt b/core/src/main/kotlin/me/rhunk/snapenhance/bridge/wrapper/ConfigWrapper.kt
deleted file mode 100644
index 47c1bc21..00000000
--- a/core/src/main/kotlin/me/rhunk/snapenhance/bridge/wrapper/ConfigWrapper.kt
+++ /dev/null
@@ -1,73 +0,0 @@
-package me.rhunk.snapenhance.bridge.wrapper
-
-import android.content.Context
-import com.google.gson.GsonBuilder
-import com.google.gson.JsonObject
-import me.rhunk.snapenhance.Logger
-import me.rhunk.snapenhance.bridge.BridgeClient
-import me.rhunk.snapenhance.bridge.FileLoaderWrapper
-import me.rhunk.snapenhance.bridge.types.BridgeFileType
-import me.rhunk.snapenhance.config.ConfigAccessor
-import me.rhunk.snapenhance.config.ConfigProperty
-
-class ConfigWrapper: ConfigAccessor() {
- companion object {
- private val gson = GsonBuilder().setPrettyPrinting().create()
- }
-
- private val file = FileLoaderWrapper(BridgeFileType.CONFIG, "{}".toByteArray(Charsets.UTF_8))
-
- fun load() {
- ConfigProperty.sortedByCategory().forEach { key ->
- set(key, key.valueContainer)
- }
-
- if (!file.isFileExists()) {
- writeConfig()
- return
- }
-
- runCatching {
- loadConfig()
- }.onFailure {
- Logger.error("Failed to load config", it)
- writeConfig()
- }
- }
-
- fun save() {
- writeConfig()
- }
-
- private fun loadConfig() {
- val configContent = file.read()
-
- val configObject: JsonObject = gson.fromJson(
- configContent.toString(Charsets.UTF_8),
- JsonObject::class.java
- )
-
- entries().forEach { (key, value) ->
- value.writeFrom(configObject.get(key.name)?.asString ?: value.read())
- }
- }
-
- fun writeConfig() {
- val configObject = JsonObject()
- entries().forEach { (key, value) ->
- configObject.addProperty(key.name, value.read())
- }
-
- file.write(gson.toJson(configObject).toByteArray(Charsets.UTF_8))
- }
-
- fun loadFromContext(context: Context) {
- file.loadFromContext(context)
- load()
- }
-
- fun loadFromBridge(bridgeClient: BridgeClient) {
- file.loadFromBridge(bridgeClient)
- load()
- }
-}
\ No newline at end of file
diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/bridge/wrapper/TranslationWrapper.kt b/core/src/main/kotlin/me/rhunk/snapenhance/bridge/wrapper/TranslationWrapper.kt
index 035d47f8..9bd2cc67 100644
--- a/core/src/main/kotlin/me/rhunk/snapenhance/bridge/wrapper/TranslationWrapper.kt
+++ b/core/src/main/kotlin/me/rhunk/snapenhance/bridge/wrapper/TranslationWrapper.kt
@@ -5,7 +5,6 @@ import com.google.gson.JsonObject
import com.google.gson.JsonParser
import me.rhunk.snapenhance.Logger
import me.rhunk.snapenhance.bridge.BridgeClient
-import me.rhunk.snapenhance.config.ConfigProperty
import me.rhunk.snapenhance.data.LocalePair
import java.util.Locale
@@ -80,18 +79,6 @@ class TranslationWrapper {
return translationMap[key] ?: key.also { Logger.debug("Missing translation for $key") }
}
- fun propertyName(property: ConfigProperty): String {
- return get("property.${property.translationKey}.name")
- }
-
- fun propertyDescription(property: ConfigProperty): String {
- return get("property.${property.translationKey}.description")
- }
-
- fun propertyOption(property: ConfigProperty, item: String): String {
- return get(property.getOptionTranslationKey(item))
- }
-
fun format(key: String, vararg args: Pair): String {
return args.fold(get(key)) { acc, pair ->
acc.replace("{${pair.first}}", pair.second)
diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/config/ConfigAccessor.kt b/core/src/main/kotlin/me/rhunk/snapenhance/config/ConfigAccessor.kt
deleted file mode 100644
index 2361bab5..00000000
--- a/core/src/main/kotlin/me/rhunk/snapenhance/config/ConfigAccessor.kt
+++ /dev/null
@@ -1,62 +0,0 @@
-package me.rhunk.snapenhance.config
-
-open class ConfigAccessor(
- private val configMap: MutableMap> = mutableMapOf()
-) {
- fun bool(key: ConfigProperty): Boolean {
- return get(key).value() as Boolean
- }
-
- fun int(key: ConfigProperty): Int {
- return get(key).value() as Int
- }
-
- fun string(key: ConfigProperty): String {
- return get(key).value() as String
- }
-
- fun double(key: ConfigProperty): Double {
- return get(key).value() as Double
- }
-
- fun float(key: ConfigProperty): Float {
- return get(key).value() as Float
- }
-
- fun long(key: ConfigProperty): Long {
- return get(key).value() as Long
- }
-
- fun short(key: ConfigProperty): Short {
- return get(key).value() as Short
- }
-
- fun byte(key: ConfigProperty): Byte {
- return get(key).value() as Byte
- }
-
- fun char(key: ConfigProperty): Char {
- return get(key).value() as Char
- }
-
- @Suppress("UNCHECKED_CAST")
- fun options(key: ConfigProperty): Map {
- return get(key).value() as Map
- }
-
- fun state(key: ConfigProperty): String {
- return get(key).value() as String
- }
-
- fun get(key: ConfigProperty): ConfigValue<*> {
- return configMap[key]!!
- }
-
- fun set(key: ConfigProperty, value: ConfigValue<*>) {
- configMap[key] = value
- }
-
- fun entries(): Set>> {
- return configMap.entries
- }
-}
\ No newline at end of file
diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/config/ConfigCategory.kt b/core/src/main/kotlin/me/rhunk/snapenhance/config/ConfigCategory.kt
deleted file mode 100644
index 47f3356c..00000000
--- a/core/src/main/kotlin/me/rhunk/snapenhance/config/ConfigCategory.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-package me.rhunk.snapenhance.config
-
-enum class ConfigCategory(
- val key: String,
- val hidden: Boolean = false
-) {
- SPYING_PRIVACY("spying_privacy"),
- MEDIA_MANAGEMENT("media_manager"),
- UI_TWEAKS("ui_tweaks"),
- UPDATES("updates"),
- CAMERA("camera"),
- EXPERIMENTAL_DEBUGGING("experimental_debugging"),
- DEVICE_SPOOFER("device_spoofer", hidden = true)
-}
diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/config/ConfigProperty.kt b/core/src/main/kotlin/me/rhunk/snapenhance/config/ConfigProperty.kt
deleted file mode 100644
index 39fa7390..00000000
--- a/core/src/main/kotlin/me/rhunk/snapenhance/config/ConfigProperty.kt
+++ /dev/null
@@ -1,417 +0,0 @@
-package me.rhunk.snapenhance.config
-
-import me.rhunk.snapenhance.config.impl.ConfigIntegerValue
-import me.rhunk.snapenhance.config.impl.ConfigStateListValue
-import me.rhunk.snapenhance.config.impl.ConfigStateSelection
-import me.rhunk.snapenhance.config.impl.ConfigStateValue
-import me.rhunk.snapenhance.config.impl.ConfigStringValue
-import me.rhunk.snapenhance.data.NotificationType
-import me.rhunk.snapenhance.features.impl.tweaks.CameraTweaks
-
-enum class ConfigProperty(
- val translationKey: String,
- val category: ConfigCategory,
- val valueContainer: ConfigValue<*>,
- val valueContainerTranslationKey: String? = null,
- val shouldAppearInSettings: Boolean = true,
- val disableValueLocalization: Boolean = false
-) {
-
- //SPYING AND PRIVACY
- MESSAGE_LOGGER("message_logger",
- ConfigCategory.SPYING_PRIVACY,
- ConfigStateValue(false)
- ),
- PREVENT_READ_RECEIPTS(
- "prevent_read_receipts",
- ConfigCategory.SPYING_PRIVACY,
- ConfigStateValue(false)
- ),
- HIDE_BITMOJI_PRESENCE(
- "hide_bitmoji_presence",
- ConfigCategory.SPYING_PRIVACY,
- ConfigStateValue(false)
- ),
- BETTER_NOTIFICATIONS(
- "better_notifications",
- ConfigCategory.SPYING_PRIVACY,
- ConfigStateListValue(
- listOf("snap", "chat", "reply_button", "download_button"),
- mutableMapOf(
- "snap" to false,
- "chat" to false,
- "reply_button" to false,
- "download_button" to false
- )
- )
- ),
- NOTIFICATION_BLACKLIST(
- "notification_blacklist",
- ConfigCategory.SPYING_PRIVACY,
- ConfigStateListValue(
- NotificationType.getIncomingValues().map { it.key },
- NotificationType.getIncomingValues().associate { it.key to false }.toMutableMap()
- ),
- valueContainerTranslationKey = "notifications",
- ),
- DISABLE_METRICS("disable_metrics",
- ConfigCategory.SPYING_PRIVACY,
- ConfigStateValue(false)
- ),
- BLOCK_ADS("block_ads",
- ConfigCategory.SPYING_PRIVACY,
- ConfigStateValue(false)
- ),
- UNLIMITED_SNAP_VIEW_TIME("unlimited_snap_view_time",
- ConfigCategory.SPYING_PRIVACY,
- ConfigStateValue(false)
- ),
- PREVENT_SENDING_MESSAGES(
- "prevent_sending_messages",
- ConfigCategory.SPYING_PRIVACY,
- ConfigStateListValue(
- NotificationType.getOutgoingValues().map { it.key },
- NotificationType.getOutgoingValues().associate { it.key to false }.toMutableMap()
- ),
- valueContainerTranslationKey = "notifications",
- ),
- ANONYMOUS_STORY_VIEW(
- "anonymous_story_view",
- ConfigCategory.SPYING_PRIVACY,
- ConfigStateValue(false)
- ),
- HIDE_TYPING_NOTIFICATION(
- "hide_typing_notification",
- ConfigCategory.SPYING_PRIVACY,
- ConfigStateValue(false)
- ),
-
- //MEDIA MANAGEMENT
- SAVE_FOLDER(
- "save_folder",
- ConfigCategory.MEDIA_MANAGEMENT,
- ConfigStringValue("", isFolderPath =true),
- ),
- AUTO_DOWNLOAD_OPTIONS(
- "auto_download_options",
- ConfigCategory.MEDIA_MANAGEMENT,
- ConfigStateListValue(
- listOf("friend_snaps", "friend_stories", "public_stories", "spotlight"),
- mutableMapOf(
- "friend_snaps" to false,
- "friend_stories" to false,
- "public_stories" to false,
- "spotlight" to false
- )
- )
- ),
- DOWNLOAD_OPTIONS(
- "download_options",
- ConfigCategory.MEDIA_MANAGEMENT,
- ConfigStateListValue(
- listOf(
- "allow_duplicate",
- "create_user_folder",
- "append_hash",
- "append_date_time",
- "append_type",
- "append_username",
- "merge_overlay"
- ),
- mutableMapOf(
- "allow_duplicate" to false,
- "create_user_folder" to true,
- "append_hash" to true,
- "append_date_time" to true,
- "append_type" to false,
- "append_username" to false,
- "merge_overlay" to false,
- )
- )
- ),
- CHAT_DOWNLOAD_CONTEXT_MENU(
- "chat_download_context_menu",
- ConfigCategory.MEDIA_MANAGEMENT,
- ConfigStateValue(false)
- ),
- GALLERY_MEDIA_SEND_OVERRIDE(
- "gallery_media_send_override",
- ConfigCategory.MEDIA_MANAGEMENT,
- ConfigStateSelection(
- listOf("OFF", "NOTE", "SNAP", "LIVE_SNAP"),
- "OFF"
- )
- ),
- AUTO_SAVE_MESSAGES("auto_save_messages",
- ConfigCategory.MEDIA_MANAGEMENT,
- ConfigStateListValue(
- listOf("CHAT", "SNAP", "NOTE", "EXTERNAL_MEDIA", "STICKER")
- )
- ),
-
- FORCE_MEDIA_SOURCE_QUALITY(
- "force_media_source_quality",
- ConfigCategory.MEDIA_MANAGEMENT,
- ConfigStateValue(false)
- ),
- DOWNLOAD_LOGGING(
- "download_logging",
- ConfigCategory.MEDIA_MANAGEMENT,
- ConfigStateListValue(
- listOf("started", "success", "progress", "failure"),
- mutableMapOf(
- "started" to false,
- "success" to true,
- "progress" to false,
- "failure" to true
- )
- )
- ),
-
- //UI AND TWEAKS
- ENABLE_FRIEND_FEED_MENU_BAR(
- "enable_friend_feed_menu_bar",
- ConfigCategory.UI_TWEAKS,
- ConfigStateValue(false)
- ),
- FRIEND_FEED_MENU_BUTTONS(
- "friend_feed_menu_buttons",
- ConfigCategory.UI_TWEAKS,
- ConfigStateListValue(
- listOf("auto_download_blacklist", "anti_auto_save", "stealth_mode", "conversation_info"),
- mutableMapOf(
- "auto_download_blacklist" to false,
- "anti_auto_save" to false,
- "stealth_mode" to true,
- "conversation_info" to true
- )
- )
- ),
- FRIEND_FEED_MENU_POSITION("friend_feed_menu_buttons_position",
- ConfigCategory.UI_TWEAKS,
- ConfigIntegerValue(1)
- ),
- HIDE_UI_ELEMENTS(
- "hide_ui_elements",
- ConfigCategory.UI_TWEAKS,
- ConfigStateListValue(
- listOf("remove_voice_record_button", "remove_stickers_button", "remove_cognac_button", "remove_live_location_share_button", "remove_call_buttons", "remove_camera_borders"),
- mutableMapOf(
- "remove_voice_record_button" to false,
- "remove_stickers_button" to false,
- "remove_cognac_button" to false,
- "remove_live_location_share_button" to false,
- "remove_call_buttons" to false,
- "remove_camera_borders" to false
- )
- )
- ),
- HIDE_STORY_SECTION(
- "hide_story_section",
- ConfigCategory.UI_TWEAKS,
- ConfigStateListValue(
- listOf("hide_friend_suggestions", "hide_friends", "hide_following", "hide_for_you"),
- mutableMapOf(
- "hide_friend_suggestions" to false,
- "hide_friends" to false,
- "hide_following" to false,
- "hide_for_you" to false
- )
- )
- ),
- STORY_VIEWER_OVERRIDE("story_viewer_override",
- ConfigCategory.UI_TWEAKS,
- ConfigStateSelection(
- listOf("OFF", "DISCOVER_PLAYBACK_SEEKBAR", "VERTICAL_STORY_VIEWER"),
- "OFF"
- )
- ),
- STREAK_EXPIRATION_INFO(
- "streak_expiration_info",
- ConfigCategory.UI_TWEAKS,
- ConfigStateValue(false)
- ),
- DISABLE_SNAP_SPLITTING(
- "disable_snap_splitting",
- ConfigCategory.UI_TWEAKS,
- ConfigStateValue(false)
- ),
- DISABLE_VIDEO_LENGTH_RESTRICTION(
- "disable_video_length_restriction",
- ConfigCategory.UI_TWEAKS,
- ConfigStateValue(false)
- ),
- SNAPCHAT_PLUS("snapchat_plus",
- ConfigCategory.UI_TWEAKS,
- ConfigStateValue(false)
- ),
- NEW_MAP_UI("new_map_ui",
- ConfigCategory.UI_TWEAKS,
- ConfigStateValue(false)
- ),
- LOCATION_SPOOF(
- "location_spoof",
- ConfigCategory.UI_TWEAKS,
- ConfigStateValue(false)
- ),
- LATITUDE(
- "latitude_value",
- ConfigCategory.UI_TWEAKS,
- ConfigStringValue("0.0000"),
- shouldAppearInSettings = false
- ),
- LONGITUDE(
- "longitude_value",
- ConfigCategory.UI_TWEAKS,
- ConfigStringValue("0.0000"),
- shouldAppearInSettings = false
- ),
- MESSAGE_PREVIEW_LENGTH(
- "message_preview_length",
- ConfigCategory.UI_TWEAKS,
- ConfigIntegerValue(20)
- ),
- UNLIMITED_CONVERSATION_PINNING(
- "unlimited_conversation_pinning",
- ConfigCategory.UI_TWEAKS,
- ConfigStateValue(false)
- ),
- DISABLE_SPOTLIGHT(
- "disable_spotlight",
- ConfigCategory.UI_TWEAKS,
- ConfigStateValue(false)
- ),
- ENABLE_APP_APPEARANCE(
- "enable_app_appearance",
- ConfigCategory.UI_TWEAKS,
- ConfigStateValue(false)
- ),
- STARTUP_PAGE_OVERRIDE(
- "startup_page_override",
- ConfigCategory.UI_TWEAKS,
- ConfigStateSelection(
- listOf(
- "OFF",
- "ngs_map_icon_container",
- "ngs_chat_icon_container",
- "ngs_camera_icon_container",
- "ngs_community_icon_container",
- "ngs_spotlight_icon_container",
- "ngs_search_icon_container"
- ),
- "OFF"
- )
- ),
- DISABLE_GOOGLE_PLAY_DIALOGS(
- "disable_google_play_dialogs",
- ConfigCategory.UI_TWEAKS,
- ConfigStateValue(false)
- ),
-
- //CAMERA
- CAMERA_DISABLE(
- "disable_camera",
- ConfigCategory.CAMERA,
- ConfigStateValue(false)
- ),
- IMMERSIVE_CAMERA_PREVIEW(
- "immersive_camera_preview",
- ConfigCategory.CAMERA,
- ConfigStateValue(false)
- ),
- OVERRIDE_PREVIEW_RESOLUTION(
- "preview_resolution",
- ConfigCategory.CAMERA,
- ConfigStateSelection(
- CameraTweaks.resolutions,
- "OFF"
- ),
- disableValueLocalization = true
- ),
- OVERRIDE_PICTURE_RESOLUTION(
- "picture_resolution",
- ConfigCategory.CAMERA,
- ConfigStateSelection(
- CameraTweaks.resolutions,
- "OFF"
- ),
- disableValueLocalization = true
- ),
- FORCE_HIGHEST_FRAME_RATE(
- "force_highest_frame_rate",
- ConfigCategory.CAMERA,
- ConfigStateValue(false)
- ),
- FORCE_CAMERA_SOURCE_ENCODING(
- "force_camera_source_encoding",
- ConfigCategory.CAMERA,
- ConfigStateValue(false)
- ),
-
- // UPDATES
- AUTO_UPDATER(
- "auto_updater",
- ConfigCategory.UPDATES,
- ConfigStateSelection(
- listOf("DISABLED", "EVERY_LAUNCH", "DAILY", "WEEKLY"),
- "DAILY"
- )
- ),
-
- // EXPERIMENTAL DEBUGGING
- APP_PASSCODE(
- "app_passcode",
- ConfigCategory.EXPERIMENTAL_DEBUGGING,
- ConfigStringValue("", isHidden = true)
- ),
- APP_LOCK_ON_RESUME(
- "app_lock_on_resume",
- ConfigCategory.EXPERIMENTAL_DEBUGGING,
- ConfigStateValue(false)
- ),
- INFINITE_STORY_BOOST(
- "infinite_story_boost",
- ConfigCategory.EXPERIMENTAL_DEBUGGING,
- ConfigStateValue(false)
- ),
- MEO_PASSCODE_BYPASS(
- "meo_passcode_bypass",
- ConfigCategory.EXPERIMENTAL_DEBUGGING,
- ConfigStateValue(false)
- ),
- AMOLED_DARK_MODE(
- "amoled_dark_mode",
- ConfigCategory.EXPERIMENTAL_DEBUGGING,
- ConfigStateValue(false)
- ),
- UNLIMITED_MULTI_SNAP(
- "unlimited_multi_snap",
- ConfigCategory.EXPERIMENTAL_DEBUGGING,
- ConfigStateValue(false)
- ),
-
- //DEVICE SPOOFER
- DEVICE_SPOOF(
- "device_spoof",
- ConfigCategory.DEVICE_SPOOFER,
- ConfigStateValue(false)
- ),
- FINGERPRINT(
- "device_fingerprint",
- ConfigCategory.DEVICE_SPOOFER,
- ConfigStringValue("")
- ),
- ANDROID_ID(
- "android_id",
- ConfigCategory.DEVICE_SPOOFER,
- ConfigStringValue("")
- );
-
- fun getOptionTranslationKey(key: String) = "option.property.${valueContainerTranslationKey ?: translationKey}.$key"
-
- companion object {
- fun sortedByCategory(): List {
- return values().sortedBy { it.category.ordinal }
- }
- }
-}
\ No newline at end of file
diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/config/ConfigValue.kt b/core/src/main/kotlin/me/rhunk/snapenhance/config/ConfigValue.kt
deleted file mode 100644
index e12c8f6c..00000000
--- a/core/src/main/kotlin/me/rhunk/snapenhance/config/ConfigValue.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-package me.rhunk.snapenhance.config
-
-abstract class ConfigValue {
- private val propertyChangeListeners = mutableListOf<(T) -> Unit>()
-
- fun addPropertyChangeListener(listener: (T) -> Unit) = propertyChangeListeners.add(listener)
- fun removePropertyChangeListener(listener: (T) -> Unit) = propertyChangeListeners.remove(listener)
-
- abstract fun value(): T
- abstract fun read(): String
- protected abstract fun write(value: String)
-
- protected fun onValueChanged() {
- propertyChangeListeners.forEach { it(value()) }
- }
-
- fun writeFrom(value: String) {
- val oldValue = read()
- write(value)
- if (oldValue != value) onValueChanged()
- }
-}
\ No newline at end of file
diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/config/impl/ConfigIntegerValue.kt b/core/src/main/kotlin/me/rhunk/snapenhance/config/impl/ConfigIntegerValue.kt
deleted file mode 100644
index e02cac04..00000000
--- a/core/src/main/kotlin/me/rhunk/snapenhance/config/impl/ConfigIntegerValue.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-package me.rhunk.snapenhance.config.impl
-
-import me.rhunk.snapenhance.config.ConfigValue
-
-class ConfigIntegerValue(
- private var value: Int
-) : ConfigValue() {
- override fun value() = value
-
- override fun read(): String {
- return value.toString()
- }
-
- override fun write(value: String) {
- this.value = value.toInt()
- }
-}
\ No newline at end of file
diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/config/impl/ConfigStateListValue.kt b/core/src/main/kotlin/me/rhunk/snapenhance/config/impl/ConfigStateListValue.kt
deleted file mode 100644
index 005d9aa6..00000000
--- a/core/src/main/kotlin/me/rhunk/snapenhance/config/impl/ConfigStateListValue.kt
+++ /dev/null
@@ -1,32 +0,0 @@
-package me.rhunk.snapenhance.config.impl
-
-import me.rhunk.snapenhance.config.ConfigValue
-
-class ConfigStateListValue(
- private val keys: List,
- private var states: MutableMap = mutableMapOf()
-) : ConfigValue