Improve settings interface, move iOS project

This commit is contained in:
2025-12-21 13:47:17 +03:00
Unverified
parent b18af36b3e
commit 0c7697aef8
23 changed files with 95 additions and 215 deletions
+5 -2
View File
@@ -18,6 +18,9 @@ build
.cxx
local.properties
keys
app/android/keys
releases
release
release
*.xcuserstate
xcuserdata
+1 -1
View File
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="XcodeMetaData" PROJECT_DIR="$PROJECT_DIR$/iosApp" PROJECT_FILE="$PROJECT_DIR$/iosApp/iosApp.xcodeproj" />
<component name="XcodeMetaData" PROJECT_DIR="$PROJECT_DIR$/iosApp" PROJECT_FILE="$PROJECT_DIR$/app/ios/iosApp.xcodeproj" />
</project>
+5 -3
View File
@@ -1,4 +1,5 @@
import com.android.build.gradle.tasks.MergeSourceSetFolders
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import java.io.FileInputStream
import java.util.Properties
@@ -50,9 +51,10 @@ android {
signingConfigs {
create("release") {
val keystoreProperties = Properties().apply {
load(FileInputStream(rootProject.file("keys/keystore.properties")))
load(FileInputStream(file("keys/keystore.properties")))
}
storeFile = rootProject.file("keys/release.jks")
storeFile = file("keys/release.jks")
keyAlias = "release"
storePassword = keystoreProperties["storePassword"].toString()
keyPassword = keystoreProperties["keyPassword"].toString()
@@ -91,7 +93,7 @@ android {
}
}
tasks.withType<com.android.build.gradle.tasks.MergeSourceSetFolders>().configureEach {
tasks.withType<MergeSourceSetFolders>().configureEach {
dependsOn(fixComposeResourcesStructure)
}
@@ -161,6 +161,7 @@
/* Begin PBXShellScriptBuildPhase section */
F36B1CEB2AD83DDC00CB74D5 /* Compile Kotlin Framework */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
@@ -175,7 +176,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "if [ \"YES\" = \"$OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED\" ]; then\n echo \"Skipping Gradle build task invocation due to OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED environment variable set to \\\"YES\\\"\"\n exit 0\nfi\ncd \"$SRCROOT/..\"\n./gradlew :composeApp:embedAndSignAppleFrameworkForXcode\n";
shellScript = "if [ \"YES\" = \"$OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED\" ]; then\n echo \"Skipping Gradle build task invocation due to OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED environment variable set to \\\"YES\\\"\"\n exit 0\nfi\ncd \"$SRCROOT/../../\"\n./gradlew :app:shared:embedAndSignAppleFrameworkForXcode\n";
};
/* End PBXShellScriptBuildPhase section */
@@ -327,7 +328,7 @@
ENABLE_PREVIEWS = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(SRCROOT)/../shared/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)\n$(SRCROOT)/../composeApp/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)",
"$(SRCROOT)/../shared/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)",
);
INFOPLIST_FILE = iosApp/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = FromChat;
@@ -359,7 +360,7 @@
ENABLE_PREVIEWS = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(SRCROOT)/../shared/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)\n$(SRCROOT)/../composeApp/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)",
"$(SRCROOT)/../shared/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)",
);
INFOPLIST_FILE = iosApp/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = FromChat;

Before

Width:  |  Height:  |  Size: 184 KiB

After

Width:  |  Height:  |  Size: 184 KiB

@@ -1,17 +1,26 @@
package ru.fromchat.core
import ru.fromchat.ui.Theme
import com.pr0gramm3r101.utils.settings.Settings
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import ru.fromchat.ui.Theme
object Settings {
private val settings = Settings.Companion()
private val settings = Settings()
private fun runIO(block: suspend CoroutineScope.() -> Unit) {
CoroutineScope(Dispatchers.IO).launch(block = block)
}
var materialYou: Boolean
get() = settings.getBoolean("materialYou", true)
set(value) = settings.putBoolean("materialYou", value)
get() = runBlocking { settings.getBoolean("materialYou", true) }
set(value) = runIO { settings.putBoolean("materialYou", value) }
var theme: Theme
get() = Theme.entries[settings.getInt("theme", Theme.AsSystem.ordinal)]
set(value) = settings.putInt("theme", value.ordinal)
get() = runBlocking { Theme.entries[settings.getInt("theme", Theme.AsSystem.ordinal)] }
set(value) = runIO { settings.putInt("theme", value.ordinal) }
}
@@ -1,70 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7555FF7A242A565900829871"
BuildableName = "FromChat.app"
BlueprintName = "iosApp"
ReferencedContainer = "container:iosApp.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
shouldAutocreateTestPlan = "YES">
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7555FF7A242A565900829871"
BuildableName = "FromChat.app"
BlueprintName = "iosApp"
ReferencedContainer = "container:iosApp.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<LocationScenarioReference
identifier = "com.apple.dt.IDEFoundation.CurrentLocationScenarioIdentifier"
referenceType = "1">
</LocationScenarioReference>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
@@ -1,22 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>iOS.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>7555FF7A242A565900829871</key>
<dict>
<key>primary</key>
<true />
</dict>
</dict>
</dict>
</plist>
@@ -1,7 +1,5 @@
package com.pr0gramm3r101.utils.settings
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.floatPreferencesKey
@@ -11,96 +9,81 @@ import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.core.stringSetPreferencesKey
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.runBlocking
class AndroidSettings(): Settings {
private val dataStore: DataStore<Preferences>
get() = DataStoreSingleton.dataStore
private val dataStore get() = DataStoreSingleton.dataStore
override fun putString(key: String, value: String) {
runBlocking {
dataStore.edit { preferences ->
preferences[stringPreferencesKey(key)] = value
}
override suspend fun putString(key: String, value: String) {
dataStore.edit { preferences ->
preferences[stringPreferencesKey(key)] = value
}
}
override fun getString(key: String, default: String) = runBlocking {
override suspend fun getString(key: String, default: String) =
dataStore.data.map { preferences ->
preferences[stringPreferencesKey(key)] ?: default
}.first()
}
override fun putInt(key: String, value: Int) = runBlocking {
override suspend fun putInt(key: String, value: Int) {
dataStore.edit { preferences ->
preferences[intPreferencesKey(key)] = value
}
Unit
}
override fun getInt(key: String, default: Int) = runBlocking {
override suspend fun getInt(key: String, default: Int) =
dataStore.data.map { preferences ->
preferences[intPreferencesKey(key)] ?: default
}.first()
}
override fun putLong(key: String, value: Long) = runBlocking {
override suspend fun putLong(key: String, value: Long) {
dataStore.edit { preferences ->
preferences[longPreferencesKey(key)] = value
}
Unit
}
override fun getLong(key: String, default: Long) = runBlocking {
override suspend fun getLong(key: String, default: Long) =
dataStore.data.map { preferences ->
preferences[longPreferencesKey(key)] ?: default
}.first()
}
override fun putFloat(key: String, value: Float) = runBlocking {
override suspend fun putFloat(key: String, value: Float) {
dataStore.edit { preferences ->
preferences[floatPreferencesKey(key)] = value
}
Unit
}
override fun getFloat(key: String, default: Float) = runBlocking {
override suspend fun getFloat(key: String, default: Float) =
dataStore.data.map { preferences ->
preferences[floatPreferencesKey(key)] ?: default
}.first()
}
override fun putBoolean(key: String, value: Boolean) = runBlocking {
override suspend fun putBoolean(key: String, value: Boolean) {
dataStore.edit { preferences ->
preferences[booleanPreferencesKey(key)] = value
}
Unit
}
override fun getBoolean(key: String, default: Boolean) = runBlocking {
override suspend fun getBoolean(key: String, default: Boolean) =
dataStore.data.map { preferences ->
preferences[booleanPreferencesKey(key)] ?: default
}.first()
}
override fun putStringSet(key: String, value: Set<String>) = runBlocking {
override suspend fun putStringSet(key: String, value: Set<String>) {
dataStore.edit { preferences ->
preferences[stringSetPreferencesKey(key)] = value
}
Unit
}
override fun getStringSet(key: String, default: Set<String>) = runBlocking {
override suspend fun getStringSet(key: String, default: Set<String>) =
dataStore.data.map { preferences ->
preferences[stringSetPreferencesKey(key)] ?: default
}.first()
}
override fun putStringList(key: String, value: List<String>) = putStringSet(key, value.toSet())
override suspend fun putStringList(key: String, value: List<String>) = putStringSet(key, value.toSet())
override fun getStringList(key: String, default: List<String>) = getStringSet(key, default.toSet()).toList()
override suspend fun getStringList(key: String, default: List<String>) = getStringSet(key, default.toSet()).toList()
override fun remove(key: String) = runBlocking {
override suspend fun remove(key: String) {
dataStore.edit { preferences ->
preferences.remove(stringPreferencesKey(key))
preferences.remove(intPreferencesKey(key))
@@ -109,6 +92,5 @@ class AndroidSettings(): Settings {
preferences.remove(booleanPreferencesKey(key))
preferences.remove(stringSetPreferencesKey(key))
}
Unit
}
}
@@ -8,26 +8,26 @@ interface Settings {
inline operator fun invoke() = settings
}
fun putString(key: String, value: String)
fun getString(key: String, default: String = ""): String
suspend fun putString(key: String, value: String)
suspend fun getString(key: String, default: String = ""): String
fun putInt(key: String, value: Int)
fun getInt(key: String, default: Int = 0): Int
suspend fun putInt(key: String, value: Int)
suspend fun getInt(key: String, default: Int = 0): Int
fun putLong(key: String, value: Long)
fun getLong(key: String, default: Long = 0L): Long
suspend fun putLong(key: String, value: Long)
suspend fun getLong(key: String, default: Long = 0L): Long
fun putFloat(key: String, value: Float)
fun getFloat(key: String, default: Float = 0f): Float
suspend fun putFloat(key: String, value: Float)
suspend fun getFloat(key: String, default: Float = 0f): Float
fun putBoolean(key: String, value: Boolean)
fun getBoolean(key: String, default: Boolean = false): Boolean
suspend fun putBoolean(key: String, value: Boolean)
suspend fun getBoolean(key: String, default: Boolean = false): Boolean
fun putStringSet(key: String, value: Set<String>)
fun getStringSet(key: String, default: Set<String> = emptySet()): Set<String>
suspend fun putStringSet(key: String, value: Set<String>)
suspend fun getStringSet(key: String, default: Set<String> = emptySet()): Set<String>
fun putStringList(key: String, value: List<String>)
fun getStringList(key: String, default: List<String> = emptyList()): List<String>
suspend fun putStringList(key: String, value: List<String>)
suspend fun getStringList(key: String, default: List<String> = emptyList()): List<String>
fun remove(key: String)
suspend fun remove(key: String)
}
@@ -6,65 +6,40 @@ import platform.Foundation.NSUserDefaults
class IosSettings : Settings {
private val defaults: NSUserDefaults = NSUserDefaults.standardUserDefaults
override fun putString(key: String, value: String) {
defaults.setObject(value, key)
override suspend fun putString(key: String, value: String) = defaults.setObject(value, key)
override suspend fun getString(key: String, default: String) = defaults.stringForKey(key) ?: default
override suspend fun putInt(key: String, value: Int) = defaults.setInteger(value.toLong(), key)
override suspend fun getInt(key: String, default: Int) = defaults.integerForKey(key).toInt()
override suspend fun putLong(key: String, value: Long) = defaults.setObject(value, key)
override suspend fun getLong(key: String, default: Long) = defaults.objectForKey(key) as? Long ?: default
override suspend fun putFloat(key: String, value: Float) = defaults.setFloat(value, key)
override suspend fun getFloat(key: String, default: Float) = defaults.floatForKey(key)
override suspend fun putBoolean(key: String, value: Boolean) = defaults.setBool(value, key)
override suspend fun getBoolean(key: String, default: Boolean) = defaults.boolForKey(key)
override suspend fun putStringSet(key: String, value: Set<String>) = defaults.setObject(value.toList(), key)
override suspend fun getStringSet(key: String, default: Set<String>): Set<String> {
return (defaults.objectForKey(key) as? List<*> ?: return default)
.filterIsInstance<String>()
.toSet()
}
override fun getString(key: String, default: String): String {
return defaults.stringForKey(key) ?: default
override suspend fun putStringList(key: String, value: List<String>) = defaults.setObject(value, key)
override suspend fun getStringList(key: String, default: List<String>): List<String> {
return (defaults.objectForKey(key) as? List<*> ?: return default)
.filterIsInstance<String>()
}
override fun putInt(key: String, value: Int) {
defaults.setInteger(value.toLong(), key)
}
override fun getInt(key: String, default: Int): Int {
return defaults.integerForKey(key).toInt()
}
override fun putLong(key: String, value: Long) {
defaults.setObject(value, key)
}
override fun getLong(key: String, default: Long): Long {
return defaults.objectForKey(key) as? Long ?: default
}
override fun putFloat(key: String, value: Float) {
defaults.setFloat(value, key)
}
override fun getFloat(key: String, default: Float): Float {
return defaults.floatForKey(key)
}
override fun putBoolean(key: String, value: Boolean) {
defaults.setBool(value, key)
}
override fun getBoolean(key: String, default: Boolean): Boolean {
return defaults.boolForKey(key)
}
override fun putStringSet(key: String, value: Set<String>) {
defaults.setObject(value.toList(), key)
}
override fun getStringSet(key: String, default: Set<String>): Set<String> {
val list = defaults.objectForKey(key) as? List<*> ?: return default
return list.filterIsInstance<String>().toSet()
}
override fun putStringList(key: String, value: List<String>) {
defaults.setObject(value, key)
}
override fun getStringList(key: String, default: List<String>): List<String> {
val list = defaults.objectForKey(key) as? List<*> ?: return default
return list.filterIsInstance<String>()
}
override fun remove(key: String) {
defaults.removeObjectForKey(key)
}
override suspend fun remove(key: String) = defaults.removeObjectForKey(key)
}