diff --git a/.gitignore b/.gitignore index 74e3a25..ef060bf 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,9 @@ build .cxx local.properties -keys +app/android/keys releases -release \ No newline at end of file +release + +*.xcuserstate +xcuserdata \ No newline at end of file diff --git a/.idea/xcode.xml b/.idea/xcode.xml index 4eb3242..6d89145 100644 --- a/.idea/xcode.xml +++ b/.idea/xcode.xml @@ -1,4 +1,4 @@ - + \ No newline at end of file diff --git a/app/android/build.gradle.kts b/app/android/build.gradle.kts index df67770..642ec6c 100644 --- a/app/android/build.gradle.kts +++ b/app/android/build.gradle.kts @@ -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().configureEach { +tasks.withType().configureEach { dependsOn(fixComposeResourcesStructure) } diff --git a/iosApp/Configuration/Config.xcconfig b/app/ios/Configuration/Config.xcconfig similarity index 100% rename from iosApp/Configuration/Config.xcconfig rename to app/ios/Configuration/Config.xcconfig diff --git a/iosApp/iosApp.xcodeproj/project.pbxproj b/app/ios/iosApp.xcodeproj/project.pbxproj similarity index 97% rename from iosApp/iosApp.xcodeproj/project.pbxproj rename to app/ios/iosApp.xcodeproj/project.pbxproj index b70fb0f..322058f 100644 --- a/iosApp/iosApp.xcodeproj/project.pbxproj +++ b/app/ios/iosApp.xcodeproj/project.pbxproj @@ -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; diff --git a/iosApp/iosApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/app/ios/iosApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from iosApp/iosApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to app/ios/iosApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/app/ios/iosApp.xcodeproj/project.xcworkspace/xcuserdata/denis0001-dev.xcuserdatad/UserInterfaceState.xcuserstate b/app/ios/iosApp.xcodeproj/project.xcworkspace/xcuserdata/denis0001-dev.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..2b08ce5 Binary files /dev/null and b/app/ios/iosApp.xcodeproj/project.xcworkspace/xcuserdata/denis0001-dev.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/iosApp/iosApp.xcodeproj/project.xcworkspace/xcuserdata/denis0001-dev.xcuserdatad/xcschemes/xcschememanagement.plist b/app/ios/iosApp.xcodeproj/project.xcworkspace/xcuserdata/denis0001-dev.xcuserdatad/xcschemes/xcschememanagement.plist similarity index 100% rename from iosApp/iosApp.xcodeproj/project.xcworkspace/xcuserdata/denis0001-dev.xcuserdatad/xcschemes/xcschememanagement.plist rename to app/ios/iosApp.xcodeproj/project.xcworkspace/xcuserdata/denis0001-dev.xcuserdatad/xcschemes/xcschememanagement.plist diff --git a/iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json b/app/ios/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json similarity index 100% rename from iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json rename to app/ios/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json diff --git a/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json b/app/ios/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json rename to app/ios/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/logo_square.png b/app/ios/iosApp/Assets.xcassets/AppIcon.appiconset/logo_square.png similarity index 100% rename from iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/logo_square.png rename to app/ios/iosApp/Assets.xcassets/AppIcon.appiconset/logo_square.png diff --git a/iosApp/iosApp/Assets.xcassets/Contents.json b/app/ios/iosApp/Assets.xcassets/Contents.json similarity index 100% rename from iosApp/iosApp/Assets.xcassets/Contents.json rename to app/ios/iosApp/Assets.xcassets/Contents.json diff --git a/iosApp/iosApp/ContentView.swift b/app/ios/iosApp/ContentView.swift similarity index 100% rename from iosApp/iosApp/ContentView.swift rename to app/ios/iosApp/ContentView.swift diff --git a/iosApp/iosApp/Info.plist b/app/ios/iosApp/Info.plist similarity index 100% rename from iosApp/iosApp/Info.plist rename to app/ios/iosApp/Info.plist diff --git a/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json b/app/ios/iosApp/Preview Content/Preview Assets.xcassets/Contents.json similarity index 100% rename from iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json rename to app/ios/iosApp/Preview Content/Preview Assets.xcassets/Contents.json diff --git a/iosApp/iosApp/iOSApp.swift b/app/ios/iosApp/iOSApp.swift similarity index 100% rename from iosApp/iosApp/iOSApp.swift rename to app/ios/iosApp/iOSApp.swift diff --git a/app/shared/src/commonMain/kotlin/ru/fromchat/core/Settings.kt b/app/shared/src/commonMain/kotlin/ru/fromchat/core/Settings.kt index 4cf302d..cd26482 100644 --- a/app/shared/src/commonMain/kotlin/ru/fromchat/core/Settings.kt +++ b/app/shared/src/commonMain/kotlin/ru/fromchat/core/Settings.kt @@ -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) } } diff --git a/iosApp/iosApp.xcodeproj/project.xcworkspace/xcuserdata/denis0001-dev.xcuserdatad/UserInterfaceState.xcuserstate b/iosApp/iosApp.xcodeproj/project.xcworkspace/xcuserdata/denis0001-dev.xcuserdatad/UserInterfaceState.xcuserstate deleted file mode 100644 index f73e8b4..0000000 Binary files a/iosApp/iosApp.xcodeproj/project.xcworkspace/xcuserdata/denis0001-dev.xcuserdatad/UserInterfaceState.xcuserstate and /dev/null differ diff --git a/iosApp/iosApp.xcodeproj/xcuserdata/denis0001-dev.xcuserdatad/xcschemes/iOS.xcscheme b/iosApp/iosApp.xcodeproj/xcuserdata/denis0001-dev.xcuserdatad/xcschemes/iOS.xcscheme deleted file mode 100644 index 0825f85..0000000 --- a/iosApp/iosApp.xcodeproj/xcuserdata/denis0001-dev.xcuserdatad/xcschemes/iOS.xcscheme +++ /dev/null @@ -1,70 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/iosApp/iosApp.xcodeproj/xcuserdata/denis0001-dev.xcuserdatad/xcschemes/xcschememanagement.plist b/iosApp/iosApp.xcodeproj/xcuserdata/denis0001-dev.xcuserdatad/xcschemes/xcschememanagement.plist deleted file mode 100644 index 2732651..0000000 --- a/iosApp/iosApp.xcodeproj/xcuserdata/denis0001-dev.xcuserdatad/xcschemes/xcschememanagement.plist +++ /dev/null @@ -1,22 +0,0 @@ - - - - - SchemeUserState - - iOS.xcscheme - - orderHint - 0 - - - SuppressBuildableAutocreation - - 7555FF7A242A565900829871 - - primary - - - - - diff --git a/utils/shared/src/androidMain/kotlin/com/pr0gramm3r101/utils/settings/AndroidSettings.kt b/utils/shared/src/androidMain/kotlin/com/pr0gramm3r101/utils/settings/AndroidSettings.kt index 5f23d9b..fe8d7b2 100644 --- a/utils/shared/src/androidMain/kotlin/com/pr0gramm3r101/utils/settings/AndroidSettings.kt +++ b/utils/shared/src/androidMain/kotlin/com/pr0gramm3r101/utils/settings/AndroidSettings.kt @@ -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 - 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) = runBlocking { + override suspend fun putStringSet(key: String, value: Set) { dataStore.edit { preferences -> preferences[stringSetPreferencesKey(key)] = value } - Unit } - override fun getStringSet(key: String, default: Set) = runBlocking { + override suspend fun getStringSet(key: String, default: Set) = dataStore.data.map { preferences -> preferences[stringSetPreferencesKey(key)] ?: default }.first() - } - override fun putStringList(key: String, value: List) = putStringSet(key, value.toSet()) + override suspend fun putStringList(key: String, value: List) = putStringSet(key, value.toSet()) - override fun getStringList(key: String, default: List) = getStringSet(key, default.toSet()).toList() + override suspend fun getStringList(key: String, default: List) = 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 } } \ No newline at end of file diff --git a/utils/shared/src/commonMain/kotlin/com/pr0gramm3r101/utils/settings/Settings.kt b/utils/shared/src/commonMain/kotlin/com/pr0gramm3r101/utils/settings/Settings.kt index 343c5cc..19ea352 100644 --- a/utils/shared/src/commonMain/kotlin/com/pr0gramm3r101/utils/settings/Settings.kt +++ b/utils/shared/src/commonMain/kotlin/com/pr0gramm3r101/utils/settings/Settings.kt @@ -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) - fun getStringSet(key: String, default: Set = emptySet()): Set + suspend fun putStringSet(key: String, value: Set) + suspend fun getStringSet(key: String, default: Set = emptySet()): Set - fun putStringList(key: String, value: List) - fun getStringList(key: String, default: List = emptyList()): List + suspend fun putStringList(key: String, value: List) + suspend fun getStringList(key: String, default: List = emptyList()): List - fun remove(key: String) + suspend fun remove(key: String) } \ No newline at end of file diff --git a/utils/shared/src/iosMain/kotlin/com/pr0gramm3r101/utils/settings/IosSettings.kt b/utils/shared/src/iosMain/kotlin/com/pr0gramm3r101/utils/settings/IosSettings.kt index 4d82e55..333b769 100644 --- a/utils/shared/src/iosMain/kotlin/com/pr0gramm3r101/utils/settings/IosSettings.kt +++ b/utils/shared/src/iosMain/kotlin/com/pr0gramm3r101/utils/settings/IosSettings.kt @@ -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) = defaults.setObject(value.toList(), key) + + override suspend fun getStringSet(key: String, default: Set): Set { + return (defaults.objectForKey(key) as? List<*> ?: return default) + .filterIsInstance() + .toSet() } - override fun getString(key: String, default: String): String { - return defaults.stringForKey(key) ?: default + override suspend fun putStringList(key: String, value: List) = defaults.setObject(value, key) + + override suspend fun getStringList(key: String, default: List): List { + return (defaults.objectForKey(key) as? List<*> ?: return default) + .filterIsInstance() } - 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) { - defaults.setObject(value.toList(), key) - } - - override fun getStringSet(key: String, default: Set): Set { - val list = defaults.objectForKey(key) as? List<*> ?: return default - return list.filterIsInstance().toSet() - } - - override fun putStringList(key: String, value: List) { - defaults.setObject(value, key) - } - - override fun getStringList(key: String, default: List): List { - val list = defaults.objectForKey(key) as? List<*> ?: return default - return list.filterIsInstance() - } - - override fun remove(key: String) { - defaults.removeObjectForKey(key) - } + override suspend fun remove(key: String) = defaults.removeObjectForKey(key) } \ No newline at end of file