🚧 Works on authentication
This commit is contained in:
@@ -3,4 +3,4 @@ exposed_version=0.61.0
|
|||||||
h2_version=2.3.232
|
h2_version=2.3.232
|
||||||
kotlin_version=2.1.10
|
kotlin_version=2.1.10
|
||||||
ktor_version=3.1.3
|
ktor_version=3.1.3
|
||||||
logback_version=1.4.14
|
logback_version=1.5.13
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||||
@@ -27,4 +29,4 @@
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
</application>
|
</application>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|||||||
@@ -4,34 +4,13 @@ import android.os.Bundle
|
|||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.activity.compose.setContent
|
import androidx.activity.compose.setContent
|
||||||
import androidx.activity.enableEdgeToEdge
|
import androidx.activity.enableEdgeToEdge
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.Spacer
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.height
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.foundation.layout.width
|
|
||||||
import androidx.compose.foundation.text.KeyboardOptions
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.automirrored.outlined.ArrowBack
|
import androidx.compose.material.icons.automirrored.outlined.ArrowBack
|
||||||
import androidx.compose.material.icons.filled.Add
|
import androidx.compose.material.icons.filled.Add
|
||||||
import androidx.compose.material3.CircularProgressIndicator
|
import androidx.compose.material3.*
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.material3.FloatingActionButton
|
|
||||||
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
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
@@ -45,20 +24,26 @@ import dev.svitan.antifed.ui.components.DropdownList
|
|||||||
import dev.svitan.antifed.ui.theme.AntiFedTheme
|
import dev.svitan.antifed.ui.theme.AntiFedTheme
|
||||||
import io.ktor.client.call.body
|
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
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
class AuthActivity : ComponentActivity() {
|
class AuthActivity : ComponentActivity() {
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
enableEdgeToEdge()
|
enableEdgeToEdge()
|
||||||
|
|
||||||
setContent {
|
setContent {
|
||||||
AntiFedTheme {
|
AntiFedTheme {
|
||||||
|
|
||||||
var serverUrl by remember { mutableStateOf("") }
|
var serverUrl by remember { mutableStateOf("") }
|
||||||
var token by remember { mutableStateOf("") }
|
var token by remember { mutableStateOf("") }
|
||||||
var authIndex by remember { mutableIntStateOf(-1) }
|
|
||||||
var authId by remember { mutableStateOf("") }
|
var authId by remember { mutableStateOf("") }
|
||||||
|
var authIndex by remember { mutableIntStateOf(-1) }
|
||||||
|
var auths by remember { mutableStateOf<List<AuthDTO>>(emptyList()) }
|
||||||
|
|
||||||
var needToCheckUrl by remember { mutableStateOf(false) }
|
var needToCheckUrl by remember { mutableStateOf(false) }
|
||||||
var checkingUrl by remember { mutableStateOf(false) }
|
var checkingUrl by remember { mutableStateOf(false) }
|
||||||
@@ -68,110 +53,99 @@ class AuthActivity : ComponentActivity() {
|
|||||||
var checkingToken by remember { mutableStateOf(false) }
|
var checkingToken by remember { mutableStateOf(false) }
|
||||||
var isTokenOk by remember { mutableStateOf(false) }
|
var isTokenOk by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
var auths by remember { mutableStateOf(listOf<AuthDTO>()) }
|
val context = LocalContext.current
|
||||||
|
val prefs = context.getSharedPreferences(
|
||||||
val prefs = LocalContext.current.getSharedPreferences(
|
stringResource(R.string.settings_prefs_key), MODE_PRIVATE
|
||||||
stringResource(R.string.settings_prefs_key),
|
|
||||||
MODE_PRIVATE
|
|
||||||
)
|
)
|
||||||
val loadedServerUrl = prefs.getString(getString(R.string.server_url_key), "") ?: ""
|
|
||||||
if (loadedServerUrl.isNotBlank()) {
|
LaunchedEffect(Unit) {
|
||||||
serverUrl = loadedServerUrl
|
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), "") ?: ""
|
||||||
|
isServerUrlOk = prefs.getBoolean(getString(R.string.server_url_okay_key), false)
|
||||||
}
|
}
|
||||||
val loadedToken = prefs.getString(getString(R.string.token_key), "") ?: ""
|
|
||||||
if (loadedToken.isNotBlank()) {
|
|
||||||
token = loadedToken
|
|
||||||
}
|
|
||||||
authId = prefs.getString(getString(R.string.auth_key), "") ?: ""
|
|
||||||
isServerUrlOk = prefs.getBoolean(getString(R.string.server_url_okay_key), false)
|
|
||||||
|
|
||||||
fun serverUrlMatches(): Boolean {
|
fun serverUrlMatches(): Boolean {
|
||||||
var re = Regex(
|
val regex = Regex("""https?://[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}(:\d+)?""")
|
||||||
"""https?://[a-zA-Z0-9\\.]+\\.[a-zA-Z0-9]+""",
|
return regex.matches(serverUrl)
|
||||||
RegexOption.DOT_MATCHES_ALL
|
|
||||||
)
|
|
||||||
return re.containsMatchIn(serverUrl)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LaunchedEffect(serverUrl) {
|
LaunchedEffect(serverUrl) {
|
||||||
if (!needToCheckUrl) return@LaunchedEffect
|
if (!needToCheckUrl) return@LaunchedEffect
|
||||||
else {
|
needToCheckUrl = false
|
||||||
isServerUrlOk = false
|
|
||||||
prefs.edit {
|
|
||||||
putBoolean(getString(R.string.server_url_okay_key), false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (serverUrl.isBlank()) return@LaunchedEffect
|
isServerUrlOk = false
|
||||||
if (!serverUrlMatches()) return@LaunchedEffect
|
prefs.edit {
|
||||||
|
putBoolean(getString(R.string.server_url_okay_key), false)
|
||||||
|
}
|
||||||
|
if (serverUrl.isBlank() || !serverUrlMatches()) return@LaunchedEffect
|
||||||
|
|
||||||
delay(1000)
|
delay(1000)
|
||||||
checkingUrl = true
|
checkingUrl = true
|
||||||
val response = client.get(serverUrl)
|
|
||||||
|
isServerUrlOk = try {
|
||||||
|
val response = client.get(serverUrl)
|
||||||
|
response.status == HttpStatusCode.OK
|
||||||
|
} catch (_: Exception) {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
checkingUrl = false
|
checkingUrl = false
|
||||||
needToCheckUrl = false
|
|
||||||
isServerUrlOk = response.status == HttpStatusCode.OK
|
|
||||||
prefs.edit {
|
prefs.edit {
|
||||||
putBoolean(getString(R.string.server_url_okay_key), isServerUrlOk)
|
putBoolean(
|
||||||
|
getString(R.string.server_url_okay_key), isServerUrlOk
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LaunchedEffect(token) {
|
LaunchedEffect(token) {
|
||||||
if (!needToCheckToken) return@LaunchedEffect
|
if (!needToCheckToken) return@LaunchedEffect
|
||||||
else isTokenOk = false
|
needToCheckToken = false
|
||||||
|
isTokenOk = false
|
||||||
|
|
||||||
if (!isServerUrlOk) return@LaunchedEffect
|
if (!isServerUrlOk || token.isBlank()) return@LaunchedEffect
|
||||||
if (token.isBlank()) return@LaunchedEffect
|
|
||||||
|
|
||||||
delay(1000)
|
delay(1000)
|
||||||
checkingToken = true
|
checkingToken = true
|
||||||
|
|
||||||
val response = client.get("$serverUrl/auth")
|
try {
|
||||||
if (response.status != HttpStatusCode.OK) {
|
val response = client.get("$serverUrl/auth") {
|
||||||
checkingToken = false
|
headers {
|
||||||
needToCheckToken = false
|
append("Authorization", "Bearer $token")
|
||||||
isTokenOk = false
|
}
|
||||||
return@LaunchedEffect
|
}
|
||||||
}
|
|
||||||
|
|
||||||
auths = response.body<List<AuthDTO>>()
|
if (response.status == HttpStatusCode.OK) {
|
||||||
if (authId.isNotBlank()) {
|
auths = response.body()
|
||||||
authIndex = auths.indexOfFirst { it.id == authId }
|
authIndex = auths.indexOfFirst { it.id == authId }
|
||||||
|
isTokenOk = true
|
||||||
|
}
|
||||||
|
} catch (_: Exception) {
|
||||||
|
isTokenOk = false
|
||||||
}
|
}
|
||||||
|
|
||||||
checkingToken = false
|
checkingToken = false
|
||||||
needToCheckToken = false
|
|
||||||
isTokenOk = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
TopAppBar(
|
TopAppBar(
|
||||||
colors = TopAppBarDefaults.topAppBarColors(
|
title = { Text(stringResource(R.string.auth)) },
|
||||||
titleContentColor = MaterialTheme.colorScheme.primary
|
|
||||||
),
|
|
||||||
title = {
|
|
||||||
Text(stringResource(R.string.auth))
|
|
||||||
},
|
|
||||||
navigationIcon = {
|
navigationIcon = {
|
||||||
IconButton(onClick = { finish() }) {
|
IconButton(onClick = { finish() }) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.AutoMirrored.Outlined.ArrowBack,
|
( Icons.AutoMirrored.Outlined.ArrowBack,
|
||||||
contentDescription = stringResource(R.string.go_back)
|
contentDescription = stringResource(R.string.go_back)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
)
|
}) { padding ->
|
||||||
},
|
|
||||||
modifier = Modifier.fillMaxSize()
|
|
||||||
) { innerPadding ->
|
|
||||||
Column(
|
Column(
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
|
||||||
verticalArrangement = Arrangement.Center,
|
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(innerPadding)
|
.padding(padding)
|
||||||
.fillMaxSize()
|
.fillMaxSize(),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
verticalArrangement = Arrangement.Center
|
||||||
) {
|
) {
|
||||||
Text(stringResource(R.string.auth), fontSize = 24.sp)
|
Text(stringResource(R.string.auth), fontSize = 24.sp)
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
@@ -179,69 +153,83 @@ class AuthActivity : ComponentActivity() {
|
|||||||
TextField(
|
TextField(
|
||||||
value = serverUrl,
|
value = serverUrl,
|
||||||
onValueChange = {
|
onValueChange = {
|
||||||
needToCheckUrl = true
|
|
||||||
serverUrl = it
|
serverUrl = it
|
||||||
|
needToCheckUrl = true
|
||||||
prefs.edit {
|
prefs.edit {
|
||||||
putString(getString(R.string.server_url_key), it)
|
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,
|
||||||
isError = !isServerUrlOk,
|
isError = !isServerUrlOk && serverUrl.isNotBlank(),
|
||||||
trailingIcon = {
|
trailingIcon = {
|
||||||
if (checkingUrl)
|
if (checkingUrl) {
|
||||||
CircularProgressIndicator(
|
CircularProgressIndicator(
|
||||||
modifier = Modifier.width(36.dp),
|
modifier = Modifier.size(24.dp)
|
||||||
color = MaterialTheme.colorScheme.secondary,
|
|
||||||
trackColor = MaterialTheme.colorScheme.surfaceVariant
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
})
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(12.dp))
|
Spacer(modifier = Modifier.height(12.dp))
|
||||||
|
|
||||||
TextField(
|
TextField(
|
||||||
value = token,
|
value = token,
|
||||||
onValueChange = {
|
onValueChange = {
|
||||||
needToCheckToken = true
|
|
||||||
token = it
|
token = it
|
||||||
|
needToCheckToken = true
|
||||||
prefs.edit {
|
prefs.edit {
|
||||||
putString(getString(R.string.token_key), it)
|
putString(
|
||||||
|
getString(R.string.token_key), it
|
||||||
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
label = { Text(stringResource(R.string.token)) },
|
label = { Text(stringResource(R.string.token)) },
|
||||||
singleLine = true,
|
singleLine = true,
|
||||||
isError = isTokenOk,
|
enabled = isServerUrlOk,
|
||||||
|
isError = !isTokenOk && token.isNotBlank(),
|
||||||
visualTransformation = PasswordVisualTransformation(),
|
visualTransformation = PasswordVisualTransformation(),
|
||||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
|
keyboardOptions = KeyboardOptions(
|
||||||
|
keyboardType = KeyboardType.Password
|
||||||
|
),
|
||||||
trailingIcon = {
|
trailingIcon = {
|
||||||
if (checkingToken) {
|
if (checkingToken) {
|
||||||
CircularProgressIndicator(
|
CircularProgressIndicator(
|
||||||
modifier = Modifier.width(36.dp),
|
modifier = Modifier.size(24.dp)
|
||||||
color = MaterialTheme.colorScheme.secondary,
|
|
||||||
trackColor = MaterialTheme.colorScheme.surfaceVariant
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
)
|
|
||||||
Spacer(modifier = Modifier.height(12.dp))
|
Spacer(modifier = Modifier.height(12.dp))
|
||||||
|
|
||||||
if (auths.isNotEmpty())
|
if (auths.isNotEmpty()) {
|
||||||
DropdownList(
|
DropdownList(
|
||||||
itemList = auths.map { it -> it.name },
|
itemList = auths.map { it.name },
|
||||||
selectedIndex = 0,
|
selectedIndex = authIndex.coerceAtLeast(0),
|
||||||
modifier = Modifier,
|
|
||||||
onItemClick = {
|
onItemClick = {
|
||||||
authIndex = it
|
authIndex = it
|
||||||
|
authId = auths[it].id
|
||||||
prefs.edit {
|
prefs.edit {
|
||||||
putInt(getString(R.string.auth_key), it)
|
putString(
|
||||||
|
getString(R.string.auth_key), authId
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
modifier = Modifier
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
||||||
FloatingActionButton(
|
FloatingActionButton(
|
||||||
onClick = { println("creating new auth!!") }
|
onClick = {
|
||||||
) {
|
println("creating new auth!!")
|
||||||
Icon(Icons.Default.Add, stringResource(R.string.create_auth))
|
}) {
|
||||||
|
Icon(
|
||||||
|
Icons.Default.Add,
|
||||||
|
contentDescription = stringResource(R.string.create_auth)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,7 +83,6 @@ fun DropdownList(
|
|||||||
Text(text = item)
|
Text(text = item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,4 +7,5 @@
|
|||||||
<string name="go_back">Ísť späť</string>
|
<string name="go_back">Ísť späť</string>
|
||||||
<string name="token">Token</string>
|
<string name="token">Token</string>
|
||||||
<string name="create_auth">Vytvoriť novú auth</string>
|
<string name="create_auth">Vytvoriť novú auth</string>
|
||||||
|
<string name="bio">Biometrika</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -12,6 +12,7 @@
|
|||||||
<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_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>
|
||||||
<!-- Strings used for fragments for navigation -->
|
<!-- Strings used for fragments for navigation -->
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
@@ -20,4 +20,14 @@ kotlin.code.style=official
|
|||||||
# Enables namespacing of each library's R class so that its R class includes only the
|
# Enables namespacing of each library's R class so that its R class includes only the
|
||||||
# resources declared in the library itself and none from the library's dependencies,
|
# resources declared in the library itself and none from the library's dependencies,
|
||||||
# thereby reducing the size of the R class for that library
|
# thereby reducing the size of the R class for that library
|
||||||
android.nonTransitiveRClass=true
|
android.nonTransitiveRClass=true
|
||||||
|
android.defaults.buildfeatures.resvalues=true
|
||||||
|
android.sdk.defaultTargetSdkToCompileSdkIfUnset=false
|
||||||
|
android.enableAppCompileTimeRClass=false
|
||||||
|
android.usesSdkInManifest.disallowed=false
|
||||||
|
android.uniquePackageNames=false
|
||||||
|
android.dependency.useConstraints=true
|
||||||
|
android.r8.strictFullModeForKeepRules=false
|
||||||
|
android.r8.optimizedResourceShrinking=false
|
||||||
|
android.builtInKotlin=false
|
||||||
|
android.newDsl=false
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
#This file is generated by updateDaemonJvm
|
||||||
|
toolchainUrl.FREE_BSD.AARCH64=https\://api.foojay.io/disco/v3.0/ids/56a19bc915b9ba2eb62ba7554c61b919/redirect
|
||||||
|
toolchainUrl.FREE_BSD.X86_64=https\://api.foojay.io/disco/v3.0/ids/398ffe3949748bfb1d5636f023d228fd/redirect
|
||||||
|
toolchainUrl.LINUX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/56a19bc915b9ba2eb62ba7554c61b919/redirect
|
||||||
|
toolchainUrl.LINUX.X86_64=https\://api.foojay.io/disco/v3.0/ids/398ffe3949748bfb1d5636f023d228fd/redirect
|
||||||
|
toolchainUrl.MAC_OS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/e99bae143b75f9a10ead10248f02055e/redirect
|
||||||
|
toolchainUrl.MAC_OS.X86_64=https\://api.foojay.io/disco/v3.0/ids/04e088f8677de3b384108493cc9481d0/redirect
|
||||||
|
toolchainUrl.UNIX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/56a19bc915b9ba2eb62ba7554c61b919/redirect
|
||||||
|
toolchainUrl.UNIX.X86_64=https\://api.foojay.io/disco/v3.0/ids/398ffe3949748bfb1d5636f023d228fd/redirect
|
||||||
|
toolchainUrl.WINDOWS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/e55dccbfe27cb97945148c61a39c89c5/redirect
|
||||||
|
toolchainUrl.WINDOWS.X86_64=https\://api.foojay.io/disco/v3.0/ids/dbd05c4936d573642f94cd149e1356c8/redirect
|
||||||
|
toolchainVendor=JETBRAINS
|
||||||
|
toolchainVersion=21
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
[versions]
|
[versions]
|
||||||
agp = "8.10.0"
|
agp = "9.1.1"
|
||||||
kotlin = "2.0.21"
|
kotlin = "2.2.10"
|
||||||
coreKtx = "1.10.1"
|
coreKtx = "1.10.1"
|
||||||
junit = "4.13.2"
|
junit = "4.13.2"
|
||||||
junitVersion = "1.1.5"
|
junitVersion = "1.1.5"
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
#Wed May 14 20:14:06 CEST 2025
|
#Wed May 14 20:14:06 CEST 2025
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.1-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ pluginManagement {
|
|||||||
gradlePluginPortal()
|
gradlePluginPortal()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
plugins {
|
||||||
|
id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0"
|
||||||
|
}
|
||||||
dependencyResolutionManagement {
|
dependencyResolutionManagement {
|
||||||
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
|
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
|
||||||
repositories {
|
repositories {
|
||||||
|
|||||||
Reference in New Issue
Block a user