diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml
index b268ef3..c1939da 100755
--- a/.idea/deploymentTargetSelector.xml
+++ b/.idea/deploymentTargetSelector.xml
@@ -4,6 +4,14 @@
+
+
+
+
+
+
+
+
diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml
index 6d0ee1c..c224ad5 100755
--- a/.idea/kotlinc.xml
+++ b/.idea/kotlinc.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 1b0289b..b1ea9a9 100755
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -1,13 +1,14 @@
/*
- * Created by sweetbread on 21.02.2025, 12:01
+ * Created by sweetbread on 22.02.2025, 15:45
* Copyright (c) 2025. All rights reserved.
- * Last modified 21.02.2025, 12:01
+ * Last modified 22.02.2025, 14:56
*/
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.compose)
+ id("com.google.devtools.ksp")
}
android {
@@ -34,11 +35,11 @@ android {
}
}
compileOptions {
- sourceCompatibility = JavaVersion.VERSION_1_8
- targetCompatibility = JavaVersion.VERSION_1_8
+ sourceCompatibility = JavaVersion.VERSION_17
+ targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
- jvmTarget = "1.8"
+ jvmTarget = "17"
}
buildFeatures {
compose = true
@@ -64,11 +65,18 @@ dependencies {
// Ktor - web client
implementation(libs.ktor.client.core)
- implementation(libs.ktor.client.cio)
+ implementation(libs.ktor.client.okhttp)
+ implementation(libs.ktor.client.logging)
// Coil - image loader
implementation(libs.coil.compose)
implementation(libs.coil.network.okhttp)
+
+ // Room - database
+ implementation(libs.androidx.room.runtime)
+ implementation(libs.androidx.lifecycle.viewmodel.ktx)
+ implementation(libs.androidx.room.ktx)
+ ksp(libs.androidx.room.compiler)
// Others
implementation(libs.splitties.base) // Syntax sugar
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 3c4028d..ea817a3 100755
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,8 +1,8 @@
-
@@ -36,6 +30,11 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/java/ru/risdeveau/pixeldragon/Common.kt b/app/src/main/java/ru/risdeveau/pixeldragon/Common.kt
index 699a23f..4221258 100755
--- a/app/src/main/java/ru/risdeveau/pixeldragon/Common.kt
+++ b/app/src/main/java/ru/risdeveau/pixeldragon/Common.kt
@@ -1,43 +1,55 @@
/*
- * Created by sweetbread on 21.02.2025, 12:01
+ * Created by sweetbread on 22.02.2025, 15:45
* Copyright (c) 2025. All rights reserved.
- * Last modified 21.02.2025, 12:01
+ * Last modified 22.02.2025, 15:45
*/
package ru.risdeveau.pixeldragon
import android.content.Context
+import android.util.Log
+import androidx.room.Room
import io.ktor.client.HttpClient
-import io.ktor.client.engine.cio.CIO
-import io.ktor.client.engine.cio.endpoint
import io.ktor.client.plugins.cache.HttpCache
+import io.ktor.client.plugins.logging.LogLevel
+import io.ktor.client.plugins.logging.Logger
+import io.ktor.client.plugins.logging.Logging
import ru.risdeveau.pixeldragon.api.getMe
+import ru.risdeveau.pixeldragon.db.AppDatabase
import splitties.init.appCtx
-val client = HttpClient(CIO) {
- engine {
- endpoint {
- maxConnectionsPerRoute = 100
- pipelineMaxSize = 20
- keepAliveTime = 30000
- connectTimeout = 15000
- connectAttempts = 5
+val client = HttpClient {
+ install(Logging) {
+ logger = object : Logger {
+ override fun log(message: String) {
+ Log.i("Ktor", message)
+ }
}
+ level = LogLevel.ALL
}
install(HttpCache)
}
val accountData = appCtx.getSharedPreferences("settings", Context.MODE_PRIVATE)
-lateinit var urlBase: String
+lateinit var homeserver: String
+lateinit var baseUrl: String
lateinit var token: String
suspend fun initCheck(): Boolean {
+ Log.d("initCheck", "checking...")
+
if (!accountData.contains("token")) return false
if (!accountData.contains("homeserver")) return false
token = accountData.getString("token", "").toString()
- urlBase = "https://${accountData.getString("homeserver", "")}/_matrix/client/v3"
+ homeserver = accountData.getString("homeserver", "").toString()
+ baseUrl = "https://$homeserver/_matrix/client/v3"
return getMe() != null
-}
\ No newline at end of file
+}
+
+val db = Room.databaseBuilder(
+ appCtx,
+ AppDatabase::class.java, "database"
+).build()
\ No newline at end of file
diff --git a/app/src/main/java/ru/risdeveau/pixeldragon/api/Room.kt b/app/src/main/java/ru/risdeveau/pixeldragon/api/Room.kt
new file mode 100755
index 0000000..7453d24
--- /dev/null
+++ b/app/src/main/java/ru/risdeveau/pixeldragon/api/Room.kt
@@ -0,0 +1,56 @@
+/*
+ * Created by sweetbread on 22.02.2025, 15:45
+ * Copyright (c) 2025. All rights reserved.
+ * Last modified 22.02.2025, 15:45
+ */
+
+package ru.risdeveau.pixeldragon.api
+
+import io.ktor.client.request.bearerAuth
+import io.ktor.client.request.get
+import io.ktor.client.statement.bodyAsText
+import io.ktor.http.HttpStatusCode
+import org.json.JSONObject
+import ru.risdeveau.pixeldragon.baseUrl
+import ru.risdeveau.pixeldragon.client
+import ru.risdeveau.pixeldragon.db
+import ru.risdeveau.pixeldragon.db.Room
+import ru.risdeveau.pixeldragon.token
+
+//fun getRooms(): List {
+// return db.roomDoa().getAllJoined()
+//}
+//
+//fun updateRooms(): List {
+//
+//}
+
+suspend fun getRooms(): List {
+ val r = client.get("$baseUrl/joined_rooms")
+ { bearerAuth(token) }
+ val rooms = JSONObject(r.bodyAsText()).getJSONArray("joined_rooms")
+ return List(
+ rooms.length()
+ ) { i -> getRoom(rooms.getString(i)) }
+}
+
+suspend fun getRoom(rid: String): Room {
+ var room = db.roomDoa().getById(rid)
+ if (room == null) {
+ val name = getState(rid, "m.room.name", "name")
+ val creator = getState(rid, "m.room.create", "creator")
+ val avatar = getState(rid, "m.room.avatar", "url")
+ room = Room(rid, name, creator, null, avatar, null, true)
+ db.roomDoa().insert(room)
+ }
+
+ return room
+}
+
+private suspend fun getState(rid: String, state: String, key: String): String? {
+ val r = client.get("$baseUrl/rooms/$rid/state/$state") { bearerAuth(token) }
+ if (r.status != HttpStatusCode.OK) return null
+ val json = JSONObject(r.bodyAsText())
+ if (!json.has(key)) return null
+ return json.getString(key)
+}
\ No newline at end of file
diff --git a/app/src/main/java/ru/risdeveau/pixeldragon/api/Server.kt b/app/src/main/java/ru/risdeveau/pixeldragon/api/Server.kt
index 7a854de..a0bdd33 100755
--- a/app/src/main/java/ru/risdeveau/pixeldragon/api/Server.kt
+++ b/app/src/main/java/ru/risdeveau/pixeldragon/api/Server.kt
@@ -1,7 +1,7 @@
/*
- * Created by sweetbread on 21.02.2025, 12:01
+ * Created by sweetbread on 22.02.2025, 17:28
* Copyright (c) 2025. All rights reserved.
- * Last modified 21.02.2025, 12:01
+ * Last modified 22.02.2025, 17:28
*/
package ru.risdeveau.pixeldragon.api
@@ -11,6 +11,7 @@ import io.ktor.client.statement.bodyAsText
import org.json.JSONException
import org.json.JSONObject
import ru.risdeveau.pixeldragon.client
+import ru.risdeveau.pixeldragon.homeserver
suspend fun isMatrixServer(url: String): Boolean {
val r = try { client.get("https://$url/.well-known/matrix/client") }
@@ -20,4 +21,11 @@ suspend fun isMatrixServer(url: String): Boolean {
catch (_: JSONException) { return false }
return true
+}
+
+fun mxcToUrl(mxc: String): String {
+ val pattern = Regex("mxc://([-a-zA-Z0-9@:%._+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6})/([a-zA-Z]+)")
+ val match = pattern.find(mxc)
+
+ return "https://$homeserver/_matrix/client/v1/media/download/${match?.groupValues[1]}/${match?.groupValues[2]}"
}
\ No newline at end of file
diff --git a/app/src/main/java/ru/risdeveau/pixeldragon/api/User.kt b/app/src/main/java/ru/risdeveau/pixeldragon/api/User.kt
index 742f8a6..a8758df 100755
--- a/app/src/main/java/ru/risdeveau/pixeldragon/api/User.kt
+++ b/app/src/main/java/ru/risdeveau/pixeldragon/api/User.kt
@@ -1,7 +1,7 @@
/*
- * Created by sweetbread on 21.02.2025, 12:09
+ * Created by sweetbread on 22.02.2025, 15:45
* Copyright (c) 2025. All rights reserved.
- * Last modified 21.02.2025, 12:01
+ * Last modified 22.02.2025, 15:45
*/
package ru.risdeveau.pixeldragon.api
@@ -18,10 +18,10 @@ import io.ktor.http.HttpStatusCode
import io.ktor.http.contentType
import org.json.JSONObject
import ru.risdeveau.pixeldragon.accountData
+import ru.risdeveau.pixeldragon.baseUrl
import ru.risdeveau.pixeldragon.client
import ru.risdeveau.pixeldragon.initCheck
import ru.risdeveau.pixeldragon.token
-import ru.risdeveau.pixeldragon.urlBase
import splitties.init.appCtx
data class Me (val userId: String, val deviceId: String)
@@ -30,7 +30,7 @@ data class Me (val userId: String, val deviceId: String)
* This func is to validate the token
*/
suspend fun getMe(): Me? {
- val r = client.get("$urlBase/account/whoami") { bearerAuth(token) }
+ val r = client.get("$baseUrl/account/whoami") { bearerAuth(token) }
if (r.status != HttpStatusCode.OK) {
Log.e("getMe", r.bodyAsText())
return null
diff --git a/app/src/main/java/ru/risdeveau/pixeldragon/db/Room.kt b/app/src/main/java/ru/risdeveau/pixeldragon/db/Room.kt
new file mode 100755
index 0000000..4c7828c
--- /dev/null
+++ b/app/src/main/java/ru/risdeveau/pixeldragon/db/Room.kt
@@ -0,0 +1,80 @@
+/*
+ * Created by sweetbread on 22.02.2025, 15:45
+ * Copyright (c) 2025. All rights reserved.
+ * Last modified 22.02.2025, 15:45
+ */
+
+package ru.risdeveau.pixeldragon.db
+
+import androidx.room.Dao
+import androidx.room.Database
+import androidx.room.Delete
+import androidx.room.Embedded
+import androidx.room.Entity
+import androidx.room.Insert
+import androidx.room.Junction
+import androidx.room.PrimaryKey
+import androidx.room.Query
+import androidx.room.Relation
+import androidx.room.RoomDatabase
+
+@Entity
+data class Room(
+ @PrimaryKey val roomId: String,
+ val name: String?,
+ val creatorId: String?,
+ val createTime: Long?,
+ val avatarUrl: String?,
+ val members: Int?,
+ val joined: Boolean
+)
+
+@Dao
+interface RoomDao {
+// @Query("SELECT * FROM room")
+// fun getAll(): List
+
+// @Query("SELECT * FROM user WHERE uid IN (:userIds)")
+// fun loadAllByIds(userIds: IntArray): List
+
+// @Query("SELECT * FROM user WHERE first_name LIKE :first AND " +
+// "last_name LIKE :last LIMIT 1")
+// fun findByName(first: String, last: String): User
+
+ @Query("SELECT * FROM room WHERE roomId LIKE :rid LIMIT 1")
+ fun getById(rid: String): Room?
+
+// @Transaction
+// @Query("SELECT * FROM room WHERE ")
+// fun getSpace(rid: String): Space
+
+ @Query("SELECT * FROM room WHERE joined = 1 AND roomId NOT IN (SELECT roomId FROM SpaceToRoom)")
+ fun getAllJoined(): List
+
+ @Insert
+ fun insert(vararg rooms: Room)
+
+ @Delete
+ fun delete(room: Room)
+}
+
+@Entity(primaryKeys = ["spaceId", "roomId"])
+data class SpaceToRoom(
+ val spaceId: String,
+ val roomId: String
+)
+
+data class Space(
+ @Embedded val space: Room,
+ @Relation(
+ parentColumn = "spaceId",
+ entityColumn = "roomId",
+ associateBy = Junction(SpaceToRoom::class)
+ )
+ val children: List
+)
+
+@Database(entities = [Room::class, SpaceToRoom::class, User::class], version = 1)
+abstract class AppDatabase : RoomDatabase() {
+ abstract fun roomDoa(): RoomDao
+}
\ No newline at end of file
diff --git a/app/src/main/java/ru/risdeveau/pixeldragon/db/User.kt b/app/src/main/java/ru/risdeveau/pixeldragon/db/User.kt
new file mode 100755
index 0000000..2e0e102
--- /dev/null
+++ b/app/src/main/java/ru/risdeveau/pixeldragon/db/User.kt
@@ -0,0 +1,18 @@
+/*
+ * Created by sweetbread on 22.02.2025, 15:45
+ * Copyright (c) 2025. All rights reserved.
+ * Last modified 21.02.2025, 13:38
+ */
+
+package ru.risdeveau.pixeldragon.db
+
+import androidx.room.ColumnInfo
+import androidx.room.Entity
+import androidx.room.PrimaryKey
+
+@Entity
+data class User(
+ @PrimaryKey val uid: String,
+ @ColumnInfo(name = "name") val name: String?,
+ @ColumnInfo(name = "avatar") val avatar: String?
+)
\ No newline at end of file
diff --git a/app/src/main/java/ru/risdeveau/pixeldragon/ui/activity/Login.kt b/app/src/main/java/ru/risdeveau/pixeldragon/ui/activity/Login.kt
index 7268283..9ef27d4 100755
--- a/app/src/main/java/ru/risdeveau/pixeldragon/ui/activity/Login.kt
+++ b/app/src/main/java/ru/risdeveau/pixeldragon/ui/activity/Login.kt
@@ -1,7 +1,7 @@
/*
- * Created by sweetbread on 21.02.2025, 12:08
+ * Created by sweetbread on 22.02.2025, 15:45
* Copyright (c) 2025. All rights reserved.
- * Last modified 21.02.2025, 12:08
+ * Last modified 22.02.2025, 15:45
*/
package ru.risdeveau.pixeldragon.ui.activity
@@ -35,15 +35,25 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.unit.dp
+import kotlinx.coroutines.DelicateCoroutinesApi
+import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import ru.risdeveau.pixeldragon.api.isMatrixServer
import ru.risdeveau.pixeldragon.api.login
+import ru.risdeveau.pixeldragon.initCheck
import ru.risdeveau.pixeldragon.ui.theme.PixelDragonTheme
import splitties.activities.start
class Login : ComponentActivity() {
+ @OptIn(DelicateCoroutinesApi::class)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
+
+
+ GlobalScope.launch {
+ if (initCheck()) start()
+ }
+
enableEdgeToEdge()
setContent {
PixelDragonTheme {
@@ -56,7 +66,10 @@ class Login : ComponentActivity() {
SnackbarHost(hostState = snackbarHostState)
}
) { innerPadding ->
- Box(Modifier.fillMaxSize().padding(innerPadding)) {
+ Box(
+ Modifier
+ .fillMaxSize()
+ .padding(innerPadding)) {
LoginField(
Modifier.align(Alignment.Center),
{ start() },
@@ -119,11 +132,10 @@ fun LoginField(modifier: Modifier = Modifier, ok: () -> Unit, err: () -> Unit) {
Button(
enabled = hmsValid && !login.isEmpty() && !pass.isEmpty(),
onClick = {
- var loginSuccess = false
- scope.launch { loginSuccess = login(homeserver, login, pass) }
-
- if (loginSuccess) ok()
- else err()
+ scope.launch {
+ if (login(homeserver, login, pass)) ok()
+ else err()
+ }
}
) {
Text("Login")
diff --git a/app/src/main/java/ru/risdeveau/pixeldragon/ui/activity/MainActivity.kt b/app/src/main/java/ru/risdeveau/pixeldragon/ui/activity/MainActivity.kt
index 0460440..fa8f8dd 100755
--- a/app/src/main/java/ru/risdeveau/pixeldragon/ui/activity/MainActivity.kt
+++ b/app/src/main/java/ru/risdeveau/pixeldragon/ui/activity/MainActivity.kt
@@ -1,7 +1,7 @@
/*
- * Created by sweetbread on 21.02.2025, 12:08
+ * Created by sweetbread on 22.02.2025, 15:45
* Copyright (c) 2025. All rights reserved.
- * Last modified 21.02.2025, 12:07
+ * Last modified 22.02.2025, 15:45
*/
package ru.risdeveau.pixeldragon.ui.activity
@@ -10,8 +10,15 @@ import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
+import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.lazy.items
+import androidx.compose.foundation.lazy.rememberLazyListState
+import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
@@ -19,22 +26,31 @@ import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults.topAppBarColors
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
-import androidx.compose.ui.tooling.preview.Preview
-import kotlinx.coroutines.DelicateCoroutinesApi
-import kotlinx.coroutines.GlobalScope
+import androidx.compose.ui.unit.dp
+import coil3.compose.SubcomposeAsyncImage
+import coil3.network.NetworkHeaders
+import coil3.network.httpHeaders
+import coil3.request.ImageRequest
+import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
-import ru.risdeveau.pixeldragon.initCheck
+import kotlinx.coroutines.withContext
+import ru.risdeveau.pixeldragon.api.getRooms
+import ru.risdeveau.pixeldragon.api.mxcToUrl
+import ru.risdeveau.pixeldragon.db.Room
+import ru.risdeveau.pixeldragon.token
import ru.risdeveau.pixeldragon.ui.theme.PixelDragonTheme
-import splitties.activities.start
+import splitties.init.appCtx
class MainActivity : ComponentActivity() {
- @OptIn(ExperimentalMaterial3Api::class, DelicateCoroutinesApi::class)
+ @OptIn(ExperimentalMaterial3Api::class)
override fun onCreate(savedInstanceState: Bundle?) {
- GlobalScope.launch {
- if (!initCheck()) start()
- }
-
super.onCreate(savedInstanceState)
enableEdgeToEdge()
@@ -54,10 +70,7 @@ class MainActivity : ComponentActivity() {
)
},
) { innerPadding ->
- Greeting(
- name = "Android",
- modifier = Modifier.padding(innerPadding)
- )
+ RoomList(Modifier.padding(innerPadding))
}
}
}
@@ -65,17 +78,67 @@ class MainActivity : ComponentActivity() {
}
@Composable
-fun Greeting(name: String, modifier: Modifier = Modifier) {
- Text(
- text = "Hello $name!",
- modifier = modifier
- )
+fun RoomList(modifier: Modifier = Modifier) {
+ var list by remember { mutableStateOf(listOf()) }
+ val coroutineScope = rememberCoroutineScope()
+ val listState = rememberLazyListState()
+
+// if (itemState.scrollToTop) {
+// LaunchedEffect(coroutineScope) {
+// Log.e("TAG", "TopCoinsScreen: scrollToTop" )
+// listState.scrollToItem(0)
+// }
+// }
+
+ LaunchedEffect(true) {
+ coroutineScope.launch {
+ withContext(Dispatchers.IO) {
+ list = getRooms()
+ }
+ }
+ }
+
+ LazyColumn(modifier = modifier, state = listState) {
+ items(list) { room ->
+ RoomItem(room = room)
+ }
+
+ item {
+ if (list.isEmpty()) {
+ Text("You have no rooms")
+ }
+ }
+ }
}
-@Preview(showBackground = true)
@Composable
-fun GreetingPreview() {
- PixelDragonTheme {
- Greeting("Android")
+fun RoomItem(modifier: Modifier = Modifier, room: Room) {
+ Row (
+ modifier.height(64.dp).fillMaxWidth().padding(8.dp)
+ ) {
+ SubcomposeAsyncImage(
+ model = ImageRequest.Builder(appCtx)
+ .data(mxcToUrl(room.avatarUrl ?: ""))
+ .httpHeaders(NetworkHeaders.Builder()
+ .set("Authorization", "Bearer $token")
+ .build())
+ .build(),
+ contentDescription = room.roomId,
+ loading = {
+ CircularProgressIndicator()
+ }
+ )
+// Column {
+ Text(room.name ?: "Unknown")
+// }
}
-}
\ No newline at end of file
+}
+
+//@Preview(showBackground = true)
+//@Composable
+//fun GreetingPreview() {
+// PixelDragonTheme {
+// RoomItem()
+// }
+//}
+
diff --git a/build.gradle.kts b/build.gradle.kts
index c57324f..b55b582 100755
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -1,7 +1,7 @@
/*
- * Created by sweetbread on 21.02.2025, 12:00
+ * Created by sweetbread on 22.02.2025, 15:45
* Copyright (c) 2025. All rights reserved.
- * Last modified 21.02.2025, 12:00
+ * Last modified 21.02.2025, 12:21
*/
// Top-level build file where you can add configuration options common to all sub-projects/modules.
@@ -9,4 +9,5 @@ plugins {
alias(libs.plugins.android.application) apply false
alias(libs.plugins.kotlin.android) apply false
alias(libs.plugins.kotlin.compose) apply false
+ id("com.google.devtools.ksp") version "2.0.21-1.0.27" apply false
}
\ No newline at end of file
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 28fbf1c..4d46867 100755
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -1,7 +1,7 @@
[versions]
agp = "8.7.3"
coil = "3.1.0"
-kotlin = "2.0.0"
+kotlin = "2.0.21"
coreKtx = "1.15.0"
junit = "4.13.2"
junitVersion = "1.2.1"
@@ -10,10 +10,15 @@ ktor = "3.1.0"
lifecycleRuntimeKtx = "2.8.7"
activityCompose = "1.10.0"
composeBom = "2025.02.00"
+room = "2.6.1"
splittiesFunPackAndroidBase = "3.0.0"
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
+androidx-lifecycle-viewmodel-ktx = { module = "androidx.lifecycle:lifecycle-viewmodel-ktx", version.ref = "room" }
+androidx-room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" }
+androidx-room-ktx = { module = "androidx.room:room-ktx", version.ref = "room" }
+androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" }
coil-compose = { module = "io.coil-kt.coil3:coil-compose", version.ref = "coil" }
coil-network-okhttp = { module = "io.coil-kt.coil3:coil-network-okhttp", version.ref = "coil" }
junit = { group = "junit", name = "junit", version.ref = "junit" }
@@ -29,8 +34,9 @@ androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-toolin
androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
androidx-material3 = { group = "androidx.compose.material3", name = "material3" }
-ktor-client-cio = { module = "io.ktor:ktor-client-cio", version.ref = "ktor" }
+ktor-client-okhttp = { module = "io.ktor:ktor-client-okhttp", version.ref = "ktor" }
ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" }
+ktor-client-logging = { module = "io.ktor:ktor-client-logging", version.ref = "ktor" }
splitties-base = { module = "com.louiscad.splitties:splitties-fun-pack-android-base", version.ref = "splittiesFunPackAndroidBase" }
[plugins]