mirror of
https://github.com/fromchat-messenger/app.git
synced 2026-09-22 19:15:05 +03:00
Remove duplicate AsyncSettings implementation, clean up
This commit is contained in:
@@ -1,18 +0,0 @@
|
|||||||
package ru.fromchat
|
|
||||||
|
|
||||||
import kotlinx.datetime.LocalDateTime
|
|
||||||
import kotlinx.datetime.format.char
|
|
||||||
|
|
||||||
val DATETIME_FORMAT = LocalDateTime.Format {
|
|
||||||
day()
|
|
||||||
char('.')
|
|
||||||
monthNumber()
|
|
||||||
char('.')
|
|
||||||
year()
|
|
||||||
|
|
||||||
char(' ')
|
|
||||||
|
|
||||||
hour()
|
|
||||||
char(':')
|
|
||||||
minute()
|
|
||||||
}
|
|
||||||
@@ -60,9 +60,7 @@ data class Message(
|
|||||||
val reply_to: Message? = null,
|
val reply_to: Message? = null,
|
||||||
val client_message_id: String? = null,
|
val client_message_id: String? = null,
|
||||||
val reactions: List<ReactionData>? = null
|
val reactions: List<ReactionData>? = null
|
||||||
) {
|
)
|
||||||
val utcTimestamp = "${timestamp}Z"
|
|
||||||
}
|
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class SendMessageRequest(
|
data class SendMessageRequest(
|
||||||
|
|||||||
@@ -35,9 +35,4 @@ data class ReactionUser(
|
|||||||
data class TypingUpdateData(
|
data class TypingUpdateData(
|
||||||
val userId: Int,
|
val userId: Int,
|
||||||
val username: String
|
val username: String
|
||||||
)
|
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class WebSocketAuthMessage(
|
|
||||||
val token: String
|
|
||||||
)
|
)
|
||||||
@@ -8,19 +8,75 @@ import kotlinx.coroutines.launch
|
|||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import ru.fromchat.ui.Theme
|
import ru.fromchat.ui.Theme
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Server configuration data
|
||||||
|
*/
|
||||||
|
data class ServerConfigData(
|
||||||
|
val serverUrl: String,
|
||||||
|
val httpsEnabled: Boolean
|
||||||
|
)
|
||||||
|
|
||||||
object Settings {
|
object Settings {
|
||||||
|
private const val MATERIAL_YOU_KEY = "materialYou"
|
||||||
|
private const val THEME_KEY = "theme"
|
||||||
|
private const val SERVER_URL_KEY = "server_url"
|
||||||
|
private const val HTTPS_ENABLED_KEY = "https_enabled"
|
||||||
|
|
||||||
private val settings = Settings()
|
private val settings = Settings()
|
||||||
|
|
||||||
private fun runIO(block: suspend CoroutineScope.() -> Unit) {
|
private fun runIO(block: suspend CoroutineScope.() -> Unit) {
|
||||||
CoroutineScope(Dispatchers.IO).launch(block = block)
|
CoroutineScope(Dispatchers.IO).launch(block = block)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun serverConfigNotInitialized(): Nothing
|
||||||
|
= throw IllegalStateException("Server config not initialized")
|
||||||
|
|
||||||
var materialYou: Boolean
|
var materialYou: Boolean
|
||||||
get() = runBlocking { settings.getBoolean("materialYou", true) }
|
get() = runBlocking { settings.getBoolean(MATERIAL_YOU_KEY, true) }
|
||||||
set(value) = runIO { settings.putBoolean("materialYou", value) }
|
set(value) = runIO { settings.putBoolean(MATERIAL_YOU_KEY, value) }
|
||||||
|
|
||||||
var theme: Theme
|
var theme: Theme
|
||||||
get() = runBlocking { Theme.entries[settings.getInt("theme", Theme.AsSystem.ordinal)] }
|
get() = runBlocking { Theme.entries[settings.getInt(THEME_KEY, Theme.AsSystem.ordinal)] }
|
||||||
set(value) = runIO { settings.putInt("theme", value.ordinal) }
|
set(value) = runIO { settings.putInt(THEME_KEY, value.ordinal) }
|
||||||
|
|
||||||
|
var serverUrl: String
|
||||||
|
get() = runBlocking {
|
||||||
|
settings.getString(SERVER_URL_KEY).ifEmpty {
|
||||||
|
serverConfigNotInitialized()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set(value) = runIO { settings.putString(SERVER_URL_KEY, value) }
|
||||||
|
|
||||||
|
var httpsEnabled: Boolean
|
||||||
|
get() = runBlocking {
|
||||||
|
if (settings.contains(HTTPS_ENABLED_KEY))
|
||||||
|
settings.getBoolean(HTTPS_ENABLED_KEY, true)
|
||||||
|
else serverConfigNotInitialized()
|
||||||
|
}
|
||||||
|
set(value) = runIO { settings.putBoolean(HTTPS_ENABLED_KEY, value) }
|
||||||
|
|
||||||
|
val hasServerConfig get() = try {
|
||||||
|
serverUrl
|
||||||
|
httpsEnabled
|
||||||
|
true
|
||||||
|
} catch (_: IllegalStateException) {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
var serverConfig: ServerConfigData
|
||||||
|
get() {
|
||||||
|
if (!hasServerConfig) {
|
||||||
|
serverUrl = "fromchat.ru"
|
||||||
|
httpsEnabled = true
|
||||||
|
|
||||||
|
return ServerConfigData("fromchat.ru", true)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ServerConfigData(serverUrl, httpsEnabled)
|
||||||
|
}
|
||||||
|
set(value) {
|
||||||
|
serverUrl = value.serverUrl
|
||||||
|
httpsEnabled = value.httpsEnabled
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
package ru.fromchat.core.config
|
package ru.fromchat.core.config
|
||||||
|
|
||||||
import com.pr0gramm3r101.utils.storage.ServerConfigData
|
|
||||||
import com.pr0gramm3r101.utils.storage.ServerConfigStorage
|
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
|
import ru.fromchat.core.ServerConfigData
|
||||||
|
import ru.fromchat.core.Settings
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Application configuration
|
* Application configuration
|
||||||
@@ -19,18 +19,15 @@ object Config {
|
|||||||
/**
|
/**
|
||||||
* Initialize configuration by loading from storage
|
* Initialize configuration by loading from storage
|
||||||
*/
|
*/
|
||||||
suspend fun initialize() {
|
fun initialize() {
|
||||||
_serverConfig.value = ServerConfigStorage.getConfig()
|
_serverConfig.value = Settings.serverConfig
|
||||||
|
|
||||||
// Set default values and prevent corruption
|
|
||||||
ServerConfigStorage.getConfig()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update server configuration
|
* Update server configuration
|
||||||
*/
|
*/
|
||||||
suspend fun updateServerConfig(config: ServerConfigData) {
|
fun updateServerConfig(config: ServerConfigData) {
|
||||||
ServerConfigStorage.saveConfig(config)
|
Settings.serverConfig = config
|
||||||
_serverConfig.value = config
|
_serverConfig.value = config
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,9 +42,4 @@ object Config {
|
|||||||
*/
|
*/
|
||||||
val webSocketUrl
|
val webSocketUrl
|
||||||
get() = "${if (config.httpsEnabled) "wss" else "ws"}://${config.serverUrl}/api/chat/ws"
|
get() = "${if (config.httpsEnabled) "wss" else "ws"}://${config.serverUrl}/api/chat/ws"
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if server configuration exists
|
|
||||||
*/
|
|
||||||
suspend fun hasServerConfig() = ServerConfigStorage.hasConfiguration()
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -307,12 +307,13 @@ fun ChatScreen(
|
|||||||
LazyColumn(
|
LazyColumn(
|
||||||
state = listState,
|
state = listState,
|
||||||
modifier = Modifier.fillMaxSize(), // Fill the entire space of the Box
|
modifier = Modifier.fillMaxSize(), // Fill the entire space of the Box
|
||||||
verticalArrangement = Arrangement.spacedBy(4.dp, alignment = Alignment.Bottom)
|
verticalArrangement = Arrangement.spacedBy(4.dp, alignment = Alignment.Bottom),
|
||||||
|
reverseLayout = true
|
||||||
) {
|
) {
|
||||||
item { Spacer(Modifier.height(innerPadding.calculateTopPadding())) } // Spacer for TopAppBar
|
item { Spacer(Modifier.height(innerPadding.calculateBottomPadding())) } // Spacer for chat input
|
||||||
|
|
||||||
items(
|
items(
|
||||||
items = panelState.messages,
|
items = panelState.messages.reversed(),
|
||||||
key = { it.id }
|
key = { it.id }
|
||||||
) { message ->
|
) { message ->
|
||||||
val isAuthor = message.user_id == currentUserId
|
val isAuthor = message.user_id == currentUserId
|
||||||
@@ -349,7 +350,7 @@ fun ChatScreen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
item { Spacer(Modifier.height(innerPadding.calculateBottomPadding())) } // Spacer for chat input
|
item { Spacer(Modifier.height(innerPadding.calculateTopPadding())) } // Spacer for TopAppBar
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,13 +40,13 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.pr0gramm3r101.utils.navigateAndWipeBackStack
|
import com.pr0gramm3r101.utils.navigateAndWipeBackStack
|
||||||
import com.pr0gramm3r101.utils.storage.ServerConfigData
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.jetbrains.compose.resources.stringResource
|
import org.jetbrains.compose.resources.stringResource
|
||||||
import ru.fromchat.Res
|
import ru.fromchat.Res
|
||||||
import ru.fromchat.api.ApiClient
|
import ru.fromchat.api.ApiClient
|
||||||
import ru.fromchat.api.WebSocketManager
|
import ru.fromchat.api.WebSocketManager
|
||||||
import ru.fromchat.back
|
import ru.fromchat.back
|
||||||
|
import ru.fromchat.core.ServerConfigData
|
||||||
import ru.fromchat.core.config.Config
|
import ru.fromchat.core.config.Config
|
||||||
import ru.fromchat.https_enabled
|
import ru.fromchat.https_enabled
|
||||||
import ru.fromchat.save_continue
|
import ru.fromchat.save_continue
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
package ru.fromchat
|
package ru.fromchat
|
||||||
|
|
||||||
import ru.fromchat.ui.App
|
|
||||||
import androidx.compose.ui.window.ComposeUIViewController
|
import androidx.compose.ui.window.ComposeUIViewController
|
||||||
|
import ru.fromchat.ui.App
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
fun MainViewController() = ComposeUIViewController { App() }
|
fun MainViewController() = ComposeUIViewController { App() }
|
||||||
|
|
||||||
|
|||||||
@@ -720,6 +720,7 @@ val ActivityInfo.launchIntent get() = Intent().apply {
|
|||||||
flags = FLAG_ACTIVITY_NEW_TASK
|
flags = FLAG_ACTIVITY_NEW_TASK
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("QueryPermissionsNeeded")
|
||||||
@RequiresPermission(Manifest.permission.QUERY_ALL_PACKAGES)
|
@RequiresPermission(Manifest.permission.QUERY_ALL_PACKAGES)
|
||||||
fun ActivityInfo.isLauncher(context: Context): Boolean {
|
fun ActivityInfo.isLauncher(context: Context): Boolean {
|
||||||
with (context) {
|
with (context) {
|
||||||
|
|||||||
+11
@@ -93,4 +93,15 @@ class AndroidSettings(): Settings {
|
|||||||
preferences.remove(stringSetPreferencesKey(key))
|
preferences.remove(stringSetPreferencesKey(key))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun contains(key: String): Boolean {
|
||||||
|
return dataStore.data.map { preferences ->
|
||||||
|
preferences.contains(stringPreferencesKey(key)) ||
|
||||||
|
preferences.contains(intPreferencesKey(key)) ||
|
||||||
|
preferences.contains(longPreferencesKey(key)) ||
|
||||||
|
preferences.contains(floatPreferencesKey(key)) ||
|
||||||
|
preferences.contains(booleanPreferencesKey(key)) ||
|
||||||
|
preferences.contains(stringSetPreferencesKey(key))
|
||||||
|
}.first()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
-128
@@ -1,128 +0,0 @@
|
|||||||
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
|
|
||||||
import androidx.datastore.preferences.core.intPreferencesKey
|
|
||||||
import androidx.datastore.preferences.core.longPreferencesKey
|
|
||||||
import androidx.datastore.preferences.core.stringPreferencesKey
|
|
||||||
import androidx.datastore.preferences.core.stringSetPreferencesKey
|
|
||||||
import kotlinx.coroutines.flow.first
|
|
||||||
import kotlinx.coroutines.flow.map
|
|
||||||
|
|
||||||
class AndroidAsyncSettings : AsyncSettings {
|
|
||||||
private val dataStore: DataStore<Preferences>
|
|
||||||
get() = DataStoreSingleton.dataStore
|
|
||||||
|
|
||||||
override suspend fun putString(key: String, value: String) {
|
|
||||||
dataStore.edit { preferences ->
|
|
||||||
preferences[stringPreferencesKey(key)] = value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun getString(key: String, default: String): String {
|
|
||||||
return dataStore.data.map { preferences ->
|
|
||||||
preferences[stringPreferencesKey(key)] ?: default
|
|
||||||
}.first()
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun putInt(key: String, value: Int) {
|
|
||||||
dataStore.edit { preferences ->
|
|
||||||
preferences[intPreferencesKey(key)] = value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun getInt(key: String, default: Int): Int {
|
|
||||||
return dataStore.data.map { preferences ->
|
|
||||||
preferences[intPreferencesKey(key)] ?: default
|
|
||||||
}.first()
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun putLong(key: String, value: Long) {
|
|
||||||
dataStore.edit { preferences ->
|
|
||||||
preferences[longPreferencesKey(key)] = value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun getLong(key: String, default: Long): Long {
|
|
||||||
return dataStore.data.map { preferences ->
|
|
||||||
preferences[longPreferencesKey(key)] ?: default
|
|
||||||
}.first()
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun putFloat(key: String, value: Float) {
|
|
||||||
dataStore.edit { preferences ->
|
|
||||||
preferences[floatPreferencesKey(key)] = value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun getFloat(key: String, default: Float): Float {
|
|
||||||
return dataStore.data.map { preferences ->
|
|
||||||
preferences[floatPreferencesKey(key)] ?: default
|
|
||||||
}.first()
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun putBoolean(key: String, value: Boolean) {
|
|
||||||
dataStore.edit { preferences ->
|
|
||||||
preferences[booleanPreferencesKey(key)] = value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun getBoolean(key: String, default: Boolean): Boolean {
|
|
||||||
return dataStore.data.map { preferences ->
|
|
||||||
preferences[booleanPreferencesKey(key)] ?: default
|
|
||||||
}.first()
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun putStringSet(key: String, value: Set<String>) {
|
|
||||||
dataStore.edit { preferences ->
|
|
||||||
preferences[stringSetPreferencesKey(key)] = value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun getStringSet(key: String, default: Set<String>): Set<String> {
|
|
||||||
return dataStore.data.map { preferences ->
|
|
||||||
preferences[stringSetPreferencesKey(key)] ?: default
|
|
||||||
}.first()
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun putStringList(key: String, value: List<String>) {
|
|
||||||
putStringSet(key, value.toSet())
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun getStringList(key: String, default: List<String>): List<String> {
|
|
||||||
return getStringSet(key, default.toSet()).toList()
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun remove(key: String) {
|
|
||||||
dataStore.edit { preferences ->
|
|
||||||
preferences.remove(stringPreferencesKey(key))
|
|
||||||
preferences.remove(intPreferencesKey(key))
|
|
||||||
preferences.remove(longPreferencesKey(key))
|
|
||||||
preferences.remove(floatPreferencesKey(key))
|
|
||||||
preferences.remove(booleanPreferencesKey(key))
|
|
||||||
preferences.remove(stringSetPreferencesKey(key))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun contains(key: String): Boolean {
|
|
||||||
return dataStore.data.map { preferences ->
|
|
||||||
preferences.contains(stringPreferencesKey(key)) ||
|
|
||||||
preferences.contains(intPreferencesKey(key)) ||
|
|
||||||
preferences.contains(longPreferencesKey(key)) ||
|
|
||||||
preferences.contains(floatPreferencesKey(key)) ||
|
|
||||||
preferences.contains(booleanPreferencesKey(key)) ||
|
|
||||||
preferences.contains(stringSetPreferencesKey(key))
|
|
||||||
}.first()
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun clear() {
|
|
||||||
dataStore.edit { preferences ->
|
|
||||||
preferences.clear()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
actual val asyncSettings: AsyncSettings = AndroidAsyncSettings()
|
|
||||||
+3
-1
@@ -1,3 +1,5 @@
|
|||||||
package com.pr0gramm3r101.utils.settings
|
package com.pr0gramm3r101.utils.settings
|
||||||
|
|
||||||
actual val settings: Settings get() = AndroidSettings()
|
actual val settings: Settings get() = AndroidSettings()
|
||||||
|
actual val secureSettings: Settings
|
||||||
|
get() = TODO("Not yet implemented")
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
package com.pr0gramm3r101.utils.settings
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Async version of Settings API using suspend functions
|
|
||||||
*/
|
|
||||||
interface AsyncSettings {
|
|
||||||
suspend fun putString(key: String, value: String)
|
|
||||||
suspend fun getString(key: String, default: String = ""): String
|
|
||||||
|
|
||||||
suspend fun putInt(key: String, value: Int)
|
|
||||||
suspend fun getInt(key: String, default: Int = 0): Int
|
|
||||||
|
|
||||||
suspend fun putLong(key: String, value: Long)
|
|
||||||
suspend fun getLong(key: String, default: Long = 0L): Long
|
|
||||||
|
|
||||||
suspend fun putFloat(key: String, value: Float)
|
|
||||||
suspend fun getFloat(key: String, default: Float = 0f): Float
|
|
||||||
|
|
||||||
suspend fun putBoolean(key: String, value: Boolean)
|
|
||||||
suspend fun getBoolean(key: String, default: Boolean = false): Boolean
|
|
||||||
|
|
||||||
suspend fun putStringSet(key: String, value: Set<String>)
|
|
||||||
suspend fun getStringSet(key: String, default: Set<String> = emptySet()): Set<String>
|
|
||||||
|
|
||||||
suspend fun putStringList(key: String, value: List<String>)
|
|
||||||
suspend fun getStringList(key: String, default: List<String> = emptyList()): List<String>
|
|
||||||
|
|
||||||
suspend fun remove(key: String)
|
|
||||||
|
|
||||||
suspend fun contains(key: String): Boolean
|
|
||||||
suspend fun clear()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Global async settings instance
|
|
||||||
*/
|
|
||||||
expect val asyncSettings: AsyncSettings
|
|
||||||
@@ -30,4 +30,6 @@ interface Settings {
|
|||||||
suspend fun getStringList(key: String, default: List<String> = emptyList()): List<String>
|
suspend fun getStringList(key: String, default: List<String> = emptyList()): List<String>
|
||||||
|
|
||||||
suspend fun remove(key: String)
|
suspend fun remove(key: String)
|
||||||
|
|
||||||
|
suspend fun contains(key: String): Boolean
|
||||||
}
|
}
|
||||||
+2
-1
@@ -1,3 +1,4 @@
|
|||||||
package com.pr0gramm3r101.utils.settings
|
package com.pr0gramm3r101.utils.settings
|
||||||
|
|
||||||
expect val settings: Settings
|
expect val settings: Settings
|
||||||
|
expect val secureSettings: Settings
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
package com.pr0gramm3r101.utils.storage
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Authentication token storage
|
|
||||||
*/
|
|
||||||
object AuthStorage {
|
|
||||||
private val storage = NamespacedStorage("auth")
|
|
||||||
|
|
||||||
suspend fun getToken(): String? {
|
|
||||||
val token = storage.getString("token")
|
|
||||||
return token.ifEmpty { null }
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun setToken(token: String?) {
|
|
||||||
if (token != null) {
|
|
||||||
storage.putString("token", token)
|
|
||||||
} else {
|
|
||||||
storage.remove("token")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun clearToken() {
|
|
||||||
storage.remove("token")
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun putString(key: String, value: String) = storage.putString(key, value)
|
|
||||||
suspend fun getString(key: String, default: String = ""): String = storage.getString(key, default)
|
|
||||||
suspend fun remove(key: String) = storage.remove(key)
|
|
||||||
}
|
|
||||||
-52
@@ -1,52 +0,0 @@
|
|||||||
package com.pr0gramm3r101.utils.storage
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Server configuration data
|
|
||||||
*/
|
|
||||||
data class ServerConfigData(
|
|
||||||
val serverUrl: String,
|
|
||||||
val httpsEnabled: Boolean
|
|
||||||
)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Server configuration storage
|
|
||||||
*/
|
|
||||||
object ServerConfigStorage {
|
|
||||||
private val storage = NamespacedStorage("server_config")
|
|
||||||
|
|
||||||
private const val SERVER_URL_KEY = "server_url"
|
|
||||||
private const val HTTPS_ENABLED_KEY = "https_enabled"
|
|
||||||
|
|
||||||
suspend fun getServerUrl() = storage.getString(SERVER_URL_KEY).ifEmpty { null }
|
|
||||||
|
|
||||||
suspend fun setServerUrl(url: String) = storage.putString(SERVER_URL_KEY, url)
|
|
||||||
|
|
||||||
suspend fun getHttpsEnabled() =
|
|
||||||
if (storage.contains(HTTPS_ENABLED_KEY))
|
|
||||||
storage.getBoolean(HTTPS_ENABLED_KEY, true)
|
|
||||||
else null
|
|
||||||
|
|
||||||
suspend fun setHttpsEnabled(enabled: Boolean) {
|
|
||||||
storage.putBoolean(HTTPS_ENABLED_KEY, enabled)
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun hasConfiguration() = getServerUrl() != null && getHttpsEnabled() != null
|
|
||||||
|
|
||||||
suspend fun getConfig(): ServerConfigData {
|
|
||||||
var url = getServerUrl()
|
|
||||||
var https = getHttpsEnabled()
|
|
||||||
|
|
||||||
if (url == null || https == null) {
|
|
||||||
url = "fromchat.ru"
|
|
||||||
https = true
|
|
||||||
saveConfig(ServerConfigData(url, https))
|
|
||||||
}
|
|
||||||
|
|
||||||
return ServerConfigData(url, https)
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun saveConfig(config: ServerConfigData) {
|
|
||||||
setServerUrl(config.serverUrl)
|
|
||||||
setHttpsEnabled(config.httpsEnabled)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
package com.pr0gramm3r101.utils.storage
|
|
||||||
|
|
||||||
import com.pr0gramm3r101.utils.settings.AsyncSettings
|
|
||||||
import com.pr0gramm3r101.utils.settings.asyncSettings
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generic key-value storage using AsyncSettings
|
|
||||||
*/
|
|
||||||
class Storage(private val settings: AsyncSettings = asyncSettings) {
|
|
||||||
suspend fun putString(key: String, value: String) = settings.putString(key, value)
|
|
||||||
suspend fun getString(key: String, default: String = ""): String = settings.getString(key, default)
|
|
||||||
|
|
||||||
suspend fun putInt(key: String, value: Int) = settings.putInt(key, value)
|
|
||||||
suspend fun getInt(key: String, default: Int = 0): Int = settings.getInt(key, default)
|
|
||||||
|
|
||||||
suspend fun putLong(key: String, value: Long) = settings.putLong(key, value)
|
|
||||||
suspend fun getLong(key: String, default: Long = 0L): Long = settings.getLong(key, default)
|
|
||||||
|
|
||||||
suspend fun putFloat(key: String, value: Float) = settings.putFloat(key, value)
|
|
||||||
suspend fun getFloat(key: String, default: Float = 0f): Float = settings.getFloat(key, default)
|
|
||||||
|
|
||||||
suspend fun putBoolean(key: String, value: Boolean) = settings.putBoolean(key, value)
|
|
||||||
suspend fun getBoolean(key: String, default: Boolean = false): Boolean = settings.getBoolean(key, default)
|
|
||||||
|
|
||||||
suspend fun putStringSet(key: String, value: Set<String>) = settings.putStringSet(key, value)
|
|
||||||
suspend fun getStringSet(key: String, default: Set<String> = emptySet()): Set<String> = settings.getStringSet(key, default)
|
|
||||||
|
|
||||||
suspend fun putStringList(key: String, value: List<String>) = settings.putStringList(key, value)
|
|
||||||
suspend fun getStringList(key: String, default: List<String> = emptyList()): List<String> = settings.getStringList(key, default)
|
|
||||||
|
|
||||||
suspend fun remove(key: String) = settings.remove(key)
|
|
||||||
suspend fun contains(key: String): Boolean = settings.contains(key)
|
|
||||||
suspend fun clear() = settings.clear()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Namespaced storage for specific features
|
|
||||||
*/
|
|
||||||
class NamespacedStorage(private val prefix: String, private val storage: Storage = Storage()) {
|
|
||||||
private fun key(name: String) = "$prefix:$name"
|
|
||||||
|
|
||||||
suspend fun putString(name: String, value: String) = storage.putString(key(name), value)
|
|
||||||
suspend fun getString(name: String, default: String = ""): String = storage.getString(key(name), default)
|
|
||||||
|
|
||||||
suspend fun putInt(name: String, value: Int) = storage.putInt(key(name), value)
|
|
||||||
suspend fun getInt(name: String, default: Int = 0): Int = storage.getInt(key(name), default)
|
|
||||||
|
|
||||||
suspend fun putLong(name: String, value: Long) = storage.putLong(key(name), value)
|
|
||||||
suspend fun getLong(name: String, default: Long = 0L): Long = storage.getLong(key(name), default)
|
|
||||||
|
|
||||||
suspend fun putFloat(name: String, value: Float) = storage.putFloat(key(name), value)
|
|
||||||
suspend fun getFloat(name: String, default: Float = 0f): Float = storage.getFloat(key(name), default)
|
|
||||||
|
|
||||||
suspend fun putBoolean(name: String, value: Boolean) = storage.putBoolean(key(name), value)
|
|
||||||
suspend fun getBoolean(name: String, default: Boolean = false): Boolean = storage.getBoolean(key(name), default)
|
|
||||||
|
|
||||||
suspend fun remove(name: String) = storage.remove(key(name))
|
|
||||||
suspend fun contains(name: String): Boolean = storage.contains(key(name))
|
|
||||||
}
|
|
||||||
@@ -1,99 +0,0 @@
|
|||||||
package com.pr0gramm3r101.utils.settings
|
|
||||||
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
import platform.Foundation.NSBundle
|
|
||||||
import platform.Foundation.NSUserDefaults
|
|
||||||
|
|
||||||
class IosAsyncSettings : AsyncSettings {
|
|
||||||
private val defaults: NSUserDefaults = NSUserDefaults.standardUserDefaults
|
|
||||||
|
|
||||||
override suspend fun putString(key: String, value: String): Unit = withContext(Dispatchers.Default) {
|
|
||||||
defaults.setObject(value, key)
|
|
||||||
defaults.synchronize()
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun getString(key: String, default: String): String = withContext(Dispatchers.Default) {
|
|
||||||
defaults.stringForKey(key) ?: default
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun putInt(key: String, value: Int): Unit = withContext(Dispatchers.Default) {
|
|
||||||
defaults.setInteger(value.toLong(), key)
|
|
||||||
defaults.synchronize()
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun getInt(key: String, default: Int): Int = withContext(Dispatchers.Default) {
|
|
||||||
defaults.integerForKey(key).toInt()
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun putLong(key: String, value: Long): Unit = withContext(Dispatchers.Default) {
|
|
||||||
defaults.setObject(value, key)
|
|
||||||
defaults.synchronize()
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun getLong(key: String, default: Long): Long = withContext(Dispatchers.Default) {
|
|
||||||
(defaults.objectForKey(key) as? platform.Foundation.NSNumber)?.longValue ?: default
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun putFloat(key: String, value: Float): Unit = withContext(Dispatchers.Default) {
|
|
||||||
defaults.setFloat(value, key)
|
|
||||||
defaults.synchronize()
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun getFloat(key: String, default: Float): Float = withContext(Dispatchers.Default) {
|
|
||||||
defaults.floatForKey(key)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun putBoolean(key: String, value: Boolean): Unit = withContext(Dispatchers.Default) {
|
|
||||||
defaults.setBool(value, key)
|
|
||||||
defaults.synchronize()
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun getBoolean(key: String, default: Boolean): Boolean = withContext(Dispatchers.Default) {
|
|
||||||
if (defaults.objectForKey(key) != null) {
|
|
||||||
defaults.boolForKey(key)
|
|
||||||
} else {
|
|
||||||
default
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun putStringSet(key: String, value: Set<String>): Unit = withContext(Dispatchers.Default) {
|
|
||||||
defaults.setObject(value.toList(), key)
|
|
||||||
defaults.synchronize()
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun getStringSet(key: String, default: Set<String>): Set<String> = withContext(Dispatchers.Default) {
|
|
||||||
val list = defaults.objectForKey(key) as? List<*> ?: return@withContext default
|
|
||||||
list.filterIsInstance<String>().toSet()
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun putStringList(key: String, value: List<String>): Unit = withContext(Dispatchers.Default) {
|
|
||||||
defaults.setObject(value, key)
|
|
||||||
defaults.synchronize()
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun getStringList(key: String, default: List<String>): List<String> = withContext(Dispatchers.Default) {
|
|
||||||
val list = defaults.objectForKey(key) as? List<*> ?: return@withContext default
|
|
||||||
list.filterIsInstance<String>()
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun remove(key: String): Unit = withContext(Dispatchers.Default) {
|
|
||||||
defaults.removeObjectForKey(key)
|
|
||||||
defaults.synchronize()
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun contains(key: String): Boolean = withContext(Dispatchers.Default) {
|
|
||||||
defaults.objectForKey(key) != null
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun clear(): Unit = withContext(Dispatchers.Default) {
|
|
||||||
val bundleId = NSBundle.mainBundle.bundleIdentifier ?: ""
|
|
||||||
val domain = defaults.persistentDomainForName(bundleId)
|
|
||||||
domain?.keys?.forEach { key ->
|
|
||||||
defaults.removeObjectForKey(key as String)
|
|
||||||
}
|
|
||||||
defaults.synchronize()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
actual val asyncSettings: AsyncSettings = IosAsyncSettings()
|
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
package com.pr0gramm3r101.utils.settings
|
package com.pr0gramm3r101.utils.settings
|
||||||
|
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
import platform.Foundation.NSUserDefaults
|
import platform.Foundation.NSUserDefaults
|
||||||
|
|
||||||
// TODO fix
|
// TODO fix
|
||||||
@@ -42,4 +44,8 @@ class IosSettings : Settings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun remove(key: String) = defaults.removeObjectForKey(key)
|
override suspend fun remove(key: String) = defaults.removeObjectForKey(key)
|
||||||
|
|
||||||
|
override suspend fun contains(key: String): Boolean = withContext(Dispatchers.Default) {
|
||||||
|
defaults.objectForKey(key) != null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+3
-1
@@ -1,3 +1,5 @@
|
|||||||
package com.pr0gramm3r101.utils.settings
|
package com.pr0gramm3r101.utils.settings
|
||||||
|
|
||||||
actual val settings: Settings get() = IosSettings()
|
actual val settings: Settings get() = IosSettings()
|
||||||
|
actual val secureSettings: Settings
|
||||||
|
get() = TODO("Not yet implemented")
|
||||||
Reference in New Issue
Block a user