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