🔨 Refactors API and saving prefs and adds data holders
This commit is contained in:
@@ -1,15 +1,56 @@
|
|||||||
package dev.svitan.antifed
|
package dev.svitan.antifed
|
||||||
|
|
||||||
import io.ktor.client.HttpClient
|
import io.ktor.client.HttpClient
|
||||||
|
import io.ktor.client.call.body
|
||||||
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
|
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
|
||||||
import io.ktor.client.engine.cio.CIO
|
import io.ktor.client.engine.cio.CIO
|
||||||
|
import io.ktor.client.request.get
|
||||||
|
import io.ktor.client.request.headers
|
||||||
|
import io.ktor.http.HttpStatusCode
|
||||||
import io.ktor.serialization.kotlinx.json.json
|
import io.ktor.serialization.kotlinx.json.json
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
val client = HttpClient(CIO) {
|
class API {
|
||||||
|
companion object {
|
||||||
|
val client = HttpClient(CIO) {
|
||||||
install(ContentNegotiation) {
|
install(ContentNegotiation) {
|
||||||
json()
|
json()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun loadAuths() {
|
||||||
|
val apiDataHolder = APIDataHolder.getInstance()
|
||||||
|
val authDataHolder = AuthDataHolder.getInstance()
|
||||||
|
|
||||||
|
val response = client.get("${apiDataHolder.serverUrl}/auth") {
|
||||||
|
headers {
|
||||||
|
append("Authorization", "Bearer ${apiDataHolder.token}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.status == HttpStatusCode.OK) {
|
||||||
|
authDataHolder.auths = response.body<List<AuthDTO>>()
|
||||||
|
authDataHolder.authIndex =
|
||||||
|
authDataHolder.auths.indexOfFirst { it.id == authDataHolder.authId }
|
||||||
|
} else {
|
||||||
|
throw Exception("Error loading auths")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class APIDataHolder {
|
||||||
|
var serverUrl: String = ""
|
||||||
|
var token: String = ""
|
||||||
|
var isOk: Boolean = false
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private var holder: APIDataHolder = APIDataHolder()
|
||||||
|
|
||||||
|
fun getInstance(): APIDataHolder {
|
||||||
|
return holder
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@@ -18,3 +59,17 @@ data class AuthDTO(
|
|||||||
val name: String,
|
val name: String,
|
||||||
val createdAt: String
|
val createdAt: String
|
||||||
)
|
)
|
||||||
|
|
||||||
|
class AuthDataHolder {
|
||||||
|
var auths: List<AuthDTO> = listOf()
|
||||||
|
var authId: String = ""
|
||||||
|
var authIndex: Int = -1
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private var holder: AuthDataHolder = AuthDataHolder()
|
||||||
|
|
||||||
|
fun getInstance(): AuthDataHolder {
|
||||||
|
return holder
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -23,10 +23,12 @@ import androidx.compose.material3.CircularProgressIndicator
|
|||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TextField
|
import androidx.compose.material3.TextField
|
||||||
import androidx.compose.material3.TopAppBar
|
import androidx.compose.material3.TopAppBar
|
||||||
|
import androidx.compose.material3.TopAppBarDefaults
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableIntStateOf
|
import androidx.compose.runtime.mutableIntStateOf
|
||||||
@@ -44,9 +46,7 @@ import androidx.compose.ui.unit.dp
|
|||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import androidx.core.content.edit
|
import androidx.core.content.edit
|
||||||
import dev.svitan.antifed.ui.theme.AntiFedTheme
|
import dev.svitan.antifed.ui.theme.AntiFedTheme
|
||||||
import io.ktor.client.call.body
|
|
||||||
import io.ktor.client.request.get
|
import io.ktor.client.request.get
|
||||||
import io.ktor.client.request.headers
|
|
||||||
import io.ktor.http.HttpStatusCode
|
import io.ktor.http.HttpStatusCode
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
|
|
||||||
@@ -61,10 +61,12 @@ class AuthActivity : ComponentActivity() {
|
|||||||
var serverUrl by remember { mutableStateOf("") }
|
var serverUrl by remember { mutableStateOf("") }
|
||||||
var token by remember { mutableStateOf("") }
|
var token by remember { mutableStateOf("") }
|
||||||
var showToken by remember { mutableStateOf(false) }
|
var showToken by remember { mutableStateOf(false) }
|
||||||
|
val apiDataHolder = APIDataHolder.getInstance()
|
||||||
|
|
||||||
var authId by remember { mutableStateOf("") }
|
var authId by remember { mutableStateOf("") }
|
||||||
var authIndex by remember { mutableIntStateOf(-1) }
|
var authIndex by remember { mutableIntStateOf(-1) }
|
||||||
var auths by remember { mutableStateOf<List<AuthDTO>>(emptyList()) }
|
var auths by remember { mutableStateOf<List<AuthDTO>>(emptyList()) }
|
||||||
|
val authDataHolder = AuthDataHolder.getInstance()
|
||||||
|
|
||||||
var needToCheckUrl by remember { mutableStateOf(false) }
|
var needToCheckUrl by remember { mutableStateOf(false) }
|
||||||
var checkingUrl by remember { mutableStateOf(false) }
|
var checkingUrl by remember { mutableStateOf(false) }
|
||||||
@@ -82,7 +84,7 @@ class AuthActivity : ComponentActivity() {
|
|||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
serverUrl = prefs.getString(getString(R.string.server_url_key), "") ?: ""
|
serverUrl = prefs.getString(getString(R.string.server_url_key), "") ?: ""
|
||||||
token = prefs.getString(getString(R.string.token_key), "") ?: ""
|
token = prefs.getString(getString(R.string.token_key), "") ?: ""
|
||||||
authId = prefs.getString(getString(R.string.auth_key), "") ?: ""
|
authId = prefs.getString(getString(R.string.auth_id_key), "") ?: ""
|
||||||
isServerUrlOk = prefs.getBoolean(getString(R.string.server_url_okay_key), false)
|
isServerUrlOk = prefs.getBoolean(getString(R.string.server_url_okay_key), false)
|
||||||
isTokenOk = prefs.getBoolean(getString(R.string.token_okay_key), false)
|
isTokenOk = prefs.getBoolean(getString(R.string.token_okay_key), false)
|
||||||
}
|
}
|
||||||
@@ -97,36 +99,25 @@ class AuthActivity : ComponentActivity() {
|
|||||||
needToCheckUrl = false
|
needToCheckUrl = false
|
||||||
|
|
||||||
isServerUrlOk = false
|
isServerUrlOk = false
|
||||||
prefs.edit {
|
|
||||||
putBoolean(getString(R.string.server_url_okay_key), false)
|
|
||||||
}
|
|
||||||
if (serverUrl.isBlank() || !serverUrlMatches()) return@LaunchedEffect
|
if (serverUrl.isBlank() || !serverUrlMatches()) return@LaunchedEffect
|
||||||
|
|
||||||
delay(1000)
|
delay(1000)
|
||||||
checkingUrl = true
|
checkingUrl = true
|
||||||
|
|
||||||
isServerUrlOk = try {
|
isServerUrlOk = try {
|
||||||
val response = client.get(serverUrl)
|
val response = API.client.get(serverUrl)
|
||||||
response.status == HttpStatusCode.OK
|
response.status == HttpStatusCode.OK
|
||||||
} catch (_: Exception) {
|
} catch (_: Exception) {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
checkingUrl = false
|
checkingUrl = false
|
||||||
prefs.edit {
|
|
||||||
putBoolean(
|
|
||||||
getString(R.string.server_url_okay_key), isServerUrlOk
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LaunchedEffect(token) {
|
LaunchedEffect(token) {
|
||||||
if (!needToCheckToken) return@LaunchedEffect
|
if (!needToCheckToken) return@LaunchedEffect
|
||||||
needToCheckToken = false
|
needToCheckToken = false
|
||||||
isTokenOk = false
|
isTokenOk = false
|
||||||
prefs.edit {
|
|
||||||
putBoolean(getString(R.string.token_okay_key), false)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isServerUrlOk || token.isBlank()) return@LaunchedEffect
|
if (!isServerUrlOk || token.isBlank()) return@LaunchedEffect
|
||||||
|
|
||||||
@@ -134,32 +125,75 @@ class AuthActivity : ComponentActivity() {
|
|||||||
checkingToken = true
|
checkingToken = true
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val response = client.get("$serverUrl/auth") {
|
API.loadAuths()
|
||||||
headers {
|
auths = authDataHolder.auths
|
||||||
append("Authorization", "Bearer $token")
|
authIndex = authDataHolder.authIndex
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (response.status == HttpStatusCode.OK) {
|
|
||||||
auths = response.body<List<AuthDTO>>()
|
|
||||||
authIndex = auths.indexOfFirst { it.id == authId }
|
|
||||||
isTokenOk = true
|
isTokenOk = true
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
isTokenOk = false
|
isTokenOk = false
|
||||||
Log.e("AuthActivity", "Error checking token", e)
|
Log.e("AuthActivity", "Error checking token", e)
|
||||||
}
|
}
|
||||||
|
|
||||||
checkingToken = false
|
checkingToken = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// saves data to prefs and data holders
|
||||||
|
LaunchedEffect(serverUrl) {
|
||||||
|
apiDataHolder.serverUrl = serverUrl
|
||||||
|
prefs.edit {
|
||||||
|
putString(
|
||||||
|
getString(R.string.server_url_key), serverUrl
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LaunchedEffect(token) {
|
||||||
|
apiDataHolder.token = token
|
||||||
|
prefs.edit {
|
||||||
|
putString(
|
||||||
|
getString(R.string.token_key), token
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LaunchedEffect(isServerUrlOk) {
|
||||||
|
apiDataHolder.isOk = isServerUrlOk && isTokenOk
|
||||||
|
prefs.edit {
|
||||||
|
putBoolean(
|
||||||
|
getString(R.string.server_url_okay_key),
|
||||||
|
isServerUrlOk
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LaunchedEffect(isTokenOk) {
|
||||||
|
apiDataHolder.isOk = isServerUrlOk && isTokenOk
|
||||||
prefs.edit {
|
prefs.edit {
|
||||||
putBoolean(getString(R.string.token_okay_key), isTokenOk)
|
putBoolean(getString(R.string.token_okay_key), isTokenOk)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LaunchedEffect(authId) {
|
||||||
|
authDataHolder.authId = authId
|
||||||
|
prefs.edit {
|
||||||
|
putString(getString(R.string.auth_id_key), authId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LaunchedEffect(auths, authIndex) {
|
||||||
|
authDataHolder.auths = auths
|
||||||
|
authDataHolder.authIndex = authIndex
|
||||||
|
}
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
TopAppBar(
|
TopAppBar(
|
||||||
title = { Text(stringResource(R.string.auth)) },
|
colors = TopAppBarDefaults.topAppBarColors(
|
||||||
|
titleContentColor = MaterialTheme.colorScheme.primary
|
||||||
|
),
|
||||||
|
title = {
|
||||||
|
Text(stringResource(R.string.auth))
|
||||||
|
},
|
||||||
navigationIcon = {
|
navigationIcon = {
|
||||||
IconButton(onClick = { finish() }) {
|
IconButton(onClick = { finish() }) {
|
||||||
Icon(
|
Icon(
|
||||||
@@ -172,6 +206,7 @@ class AuthActivity : ComponentActivity() {
|
|||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(padding)
|
.padding(padding)
|
||||||
|
.padding(bottom = 64.dp)
|
||||||
.imePadding()
|
.imePadding()
|
||||||
.fillMaxSize(),
|
.fillMaxSize(),
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
@@ -185,11 +220,7 @@ class AuthActivity : ComponentActivity() {
|
|||||||
onValueChange = {
|
onValueChange = {
|
||||||
serverUrl = it
|
serverUrl = it
|
||||||
needToCheckUrl = true
|
needToCheckUrl = true
|
||||||
prefs.edit {
|
|
||||||
putString(
|
|
||||||
getString(R.string.server_url_key), it
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
label = { Text(stringResource(R.string.server_url)) },
|
label = { Text(stringResource(R.string.server_url)) },
|
||||||
singleLine = true,
|
singleLine = true,
|
||||||
@@ -209,11 +240,6 @@ class AuthActivity : ComponentActivity() {
|
|||||||
onValueChange = {
|
onValueChange = {
|
||||||
token = it
|
token = it
|
||||||
needToCheckToken = true
|
needToCheckToken = true
|
||||||
prefs.edit {
|
|
||||||
putString(
|
|
||||||
getString(R.string.token_key), it
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
label = { Text(stringResource(R.string.token)) },
|
label = { Text(stringResource(R.string.token)) },
|
||||||
singleLine = true,
|
singleLine = true,
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
<string name="server_url_key" translatable="false">server_url</string>
|
<string name="server_url_key" translatable="false">server_url</string>
|
||||||
<string name="server_url_okay_key" translatable="false">server_url_okay</string>
|
<string name="server_url_okay_key" translatable="false">server_url_okay</string>
|
||||||
<string name="token_key" translatable="false">token</string>
|
<string name="token_key" translatable="false">token</string>
|
||||||
<string name="auth_key" translatable="false">auth_id</string>
|
<string name="auth_id_key" translatable="false">auth_id</string>
|
||||||
<string name="create_auth">Create new auth</string>
|
<string name="create_auth">Create new auth</string>
|
||||||
<string name="bio">Biometrics</string>
|
<string name="bio">Biometrics</string>
|
||||||
<string name="show_token">Show token</string>
|
<string name="show_token">Show token</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user