WIP: Persist NoteEntities
This commit is contained in:
		
							parent
							
								
									646e2a5f1a
								
							
						
					
					
						commit
						ba0cbcef09
					
				@ -4,7 +4,7 @@
 | 
				
			|||||||
    <selectionStates>
 | 
					    <selectionStates>
 | 
				
			||||||
      <SelectionState runConfigName="app">
 | 
					      <SelectionState runConfigName="app">
 | 
				
			||||||
        <option name="selectionMode" value="DROPDOWN" />
 | 
					        <option name="selectionMode" value="DROPDOWN" />
 | 
				
			||||||
        <DropdownSelection timestamp="2025-04-29T15:21:34.999046322Z">
 | 
					        <DropdownSelection timestamp="2025-04-29T16:02:42.921287190Z">
 | 
				
			||||||
          <Target type="DEFAULT_BOOT">
 | 
					          <Target type="DEFAULT_BOOT">
 | 
				
			||||||
            <handle>
 | 
					            <handle>
 | 
				
			||||||
              <DeviceId pluginId="PhysicalDevice" identifier="serial=R52N50NLGRT" />
 | 
					              <DeviceId pluginId="PhysicalDevice" identifier="serial=R52N50NLGRT" />
 | 
				
			||||||
 | 
				
			|||||||
@ -2,6 +2,7 @@ plugins {
 | 
				
			|||||||
    alias(libs.plugins.android.application)
 | 
					    alias(libs.plugins.android.application)
 | 
				
			||||||
    alias(libs.plugins.kotlin.android)
 | 
					    alias(libs.plugins.kotlin.android)
 | 
				
			||||||
    alias(libs.plugins.kotlin.compose)
 | 
					    alias(libs.plugins.kotlin.compose)
 | 
				
			||||||
 | 
					    alias(libs.plugins.ksp) // NEU
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
android {
 | 
					android {
 | 
				
			||||||
@ -56,4 +57,9 @@ dependencies {
 | 
				
			|||||||
    debugImplementation(libs.androidx.ui.tooling)
 | 
					    debugImplementation(libs.androidx.ui.tooling)
 | 
				
			||||||
    debugImplementation(libs.androidx.ui.test.manifest)
 | 
					    debugImplementation(libs.androidx.ui.test.manifest)
 | 
				
			||||||
    implementation(libs.androidx.foundation)
 | 
					    implementation(libs.androidx.foundation)
 | 
				
			||||||
 | 
					    implementation(libs.androidx.room.runtime)
 | 
				
			||||||
 | 
					    implementation(libs.androidx.room.ktx)
 | 
				
			||||||
 | 
					    implementation(libs.lifecycle.livedata.ktx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ksp(libs.androidx.room.compiler)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -10,10 +10,15 @@ import androidx.activity.result.PickVisualMediaRequest
 | 
				
			|||||||
import androidx.activity.result.contract.ActivityResultContracts
 | 
					import androidx.activity.result.contract.ActivityResultContracts
 | 
				
			||||||
import androidx.compose.runtime.*
 | 
					import androidx.compose.runtime.*
 | 
				
			||||||
import androidx.compose.ui.platform.LocalContext
 | 
					import androidx.compose.ui.platform.LocalContext
 | 
				
			||||||
 | 
					import androidx.lifecycle.viewmodel.compose.viewModel
 | 
				
			||||||
 | 
					import come.stormborntales.notevault.data.local.AppDatabase
 | 
				
			||||||
import come.stormborntales.notevault.data.model.NoteEntry
 | 
					import come.stormborntales.notevault.data.model.NoteEntry
 | 
				
			||||||
 | 
					import come.stormborntales.notevault.data.repository.NoteRepository
 | 
				
			||||||
import come.stormborntales.notevault.ui.screens.AddNoteDialog
 | 
					import come.stormborntales.notevault.ui.screens.AddNoteDialog
 | 
				
			||||||
import come.stormborntales.notevault.ui.screens.MainScreen
 | 
					import come.stormborntales.notevault.ui.screens.MainScreen
 | 
				
			||||||
import come.stormborntales.notevault.ui.theme.NoteVaultTheme
 | 
					import come.stormborntales.notevault.ui.theme.NoteVaultTheme
 | 
				
			||||||
 | 
					import come.stormborntales.notevault.ui.viewmodel.NoteViewModel
 | 
				
			||||||
 | 
					import come.stormborntales.notevault.ui.viewmodel.NoteViewModelFactory
 | 
				
			||||||
import kotlinx.coroutines.Dispatchers
 | 
					import kotlinx.coroutines.Dispatchers
 | 
				
			||||||
import kotlinx.coroutines.launch
 | 
					import kotlinx.coroutines.launch
 | 
				
			||||||
import java.io.File
 | 
					import java.io.File
 | 
				
			||||||
@ -22,9 +27,14 @@ import java.io.InputStream
 | 
				
			|||||||
class MainActivity : ComponentActivity() {
 | 
					class MainActivity : ComponentActivity() {
 | 
				
			||||||
    override fun onCreate(savedInstanceState: Bundle?) {
 | 
					    override fun onCreate(savedInstanceState: Bundle?) {
 | 
				
			||||||
        super.onCreate(savedInstanceState)
 | 
					        super.onCreate(savedInstanceState)
 | 
				
			||||||
 | 
					        val applicationContext = applicationContext
 | 
				
			||||||
 | 
					        val database = AppDatabase.getDatabase(applicationContext)
 | 
				
			||||||
 | 
					        val repository = NoteRepository(database.noteDao())
 | 
				
			||||||
 | 
					        val viewModelFactory = NoteViewModelFactory(repository)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        setContent {
 | 
					        setContent {
 | 
				
			||||||
            NoteVaultTheme {
 | 
					            NoteVaultTheme {
 | 
				
			||||||
 | 
					                val viewModel: NoteViewModel = viewModel(factory = viewModelFactory)
 | 
				
			||||||
                val context = LocalContext.current
 | 
					                val context = LocalContext.current
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // Globale Notenliste
 | 
					                // Globale Notenliste
 | 
				
			||||||
@ -62,43 +72,16 @@ class MainActivity : ComponentActivity() {
 | 
				
			|||||||
                    AddNoteDialog(
 | 
					                    AddNoteDialog(
 | 
				
			||||||
                        onDismiss = { showDialog = false },
 | 
					                        onDismiss = { showDialog = false },
 | 
				
			||||||
                        onSave = { title, composer, year, genre, description ->
 | 
					                        onSave = { title, composer, year, genre, description ->
 | 
				
			||||||
                            scope.launch(Dispatchers.IO) {
 | 
					                            viewModel.addNote(
 | 
				
			||||||
                                val copiedUris = selectedUris.mapNotNull { uri ->
 | 
					                                context = context,
 | 
				
			||||||
                                    try {
 | 
					                                title = title,
 | 
				
			||||||
                                        val inputStream: InputStream? = context.contentResolver.openInputStream(uri)
 | 
					                                composer = composer,
 | 
				
			||||||
                                        val extension = MimeTypeMap.getSingleton()
 | 
					                                year = year,
 | 
				
			||||||
                                            .getExtensionFromMimeType(context.contentResolver.getType(uri)) ?: "jpg" // Fallback
 | 
					                                genre = genre,
 | 
				
			||||||
 | 
					                                description = description,
 | 
				
			||||||
                                        val outputFile = File(context.filesDir, "note_${System.currentTimeMillis()}.$extension")
 | 
					                                selectedUris = selectedUris,
 | 
				
			||||||
                                        inputStream?.use { input ->
 | 
					                                onDone = { showDialog = false }
 | 
				
			||||||
                                            outputFile.outputStream().use { output ->
 | 
					                            )
 | 
				
			||||||
                                                input.copyTo(output)
 | 
					 | 
				
			||||||
                                            }
 | 
					 | 
				
			||||||
                                        }
 | 
					 | 
				
			||||||
                                        Uri.fromFile(outputFile)
 | 
					 | 
				
			||||||
                                    } catch (e: Exception) {
 | 
					 | 
				
			||||||
                                        e.printStackTrace()
 | 
					 | 
				
			||||||
                                        null
 | 
					 | 
				
			||||||
                                    }
 | 
					 | 
				
			||||||
                                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                                if (copiedUris.isNotEmpty()) {
 | 
					 | 
				
			||||||
                                    notes.add(
 | 
					 | 
				
			||||||
                                        NoteEntry(
 | 
					 | 
				
			||||||
                                            title = title,
 | 
					 | 
				
			||||||
                                            images = copiedUris,
 | 
					 | 
				
			||||||
                                            composer = composer,
 | 
					 | 
				
			||||||
                                            year = year,
 | 
					 | 
				
			||||||
                                            genre = genre,
 | 
					 | 
				
			||||||
                                            description = description
 | 
					 | 
				
			||||||
                                        )
 | 
					 | 
				
			||||||
                                    )
 | 
					 | 
				
			||||||
                                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                                showDialog = false
 | 
					 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    )
 | 
					                    )
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,32 @@
 | 
				
			|||||||
 | 
					package come.stormborntales.notevault.data.local
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import android.content.Context
 | 
				
			||||||
 | 
					import androidx.room.Database
 | 
				
			||||||
 | 
					import androidx.room.Room
 | 
				
			||||||
 | 
					import androidx.room.RoomDatabase
 | 
				
			||||||
 | 
					import androidx.room.TypeConverters
 | 
				
			||||||
 | 
					import come.stormborntales.notevault.data.local.dao.NoteDao
 | 
				
			||||||
 | 
					import come.stormborntales.notevault.data.local.entity.NoteEntity
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@Database(entities = [NoteEntity::class], version = 1)
 | 
				
			||||||
 | 
					@TypeConverters(UriListConverter::class)
 | 
				
			||||||
 | 
					abstract class AppDatabase : RoomDatabase() {
 | 
				
			||||||
 | 
					    abstract fun noteDao(): NoteDao
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    companion object {
 | 
				
			||||||
 | 
					        @Volatile
 | 
				
			||||||
 | 
					        private var INSTANCE: AppDatabase? = null
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        fun getDatabase(context: Context): AppDatabase {
 | 
				
			||||||
 | 
					            return INSTANCE ?: synchronized(this) {
 | 
				
			||||||
 | 
					                val instance = Room.databaseBuilder(
 | 
				
			||||||
 | 
					                    context.applicationContext,
 | 
				
			||||||
 | 
					                    AppDatabase::class.java,
 | 
				
			||||||
 | 
					                    "note_database"
 | 
				
			||||||
 | 
					                ).build()
 | 
				
			||||||
 | 
					                INSTANCE = instance
 | 
				
			||||||
 | 
					                instance
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					package come.stormborntales.notevault.data.local
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import androidx.room.TypeConverter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class UriListConverter {
 | 
				
			||||||
 | 
					    @TypeConverter
 | 
				
			||||||
 | 
					    fun fromList(list: List<String>): String = list.joinToString(",")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @TypeConverter
 | 
				
			||||||
 | 
					    fun toList(data: String): List<String> = if (data.isBlank()) emptyList() else data.split(",")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,21 @@
 | 
				
			|||||||
 | 
					package come.stormborntales.notevault.data.local.dao
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import androidx.room.Dao
 | 
				
			||||||
 | 
					import androidx.room.Delete
 | 
				
			||||||
 | 
					import androidx.room.Insert
 | 
				
			||||||
 | 
					import androidx.room.OnConflictStrategy
 | 
				
			||||||
 | 
					import androidx.room.Query
 | 
				
			||||||
 | 
					import come.stormborntales.notevault.data.local.entity.NoteEntity
 | 
				
			||||||
 | 
					import kotlinx.coroutines.flow.Flow
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@Dao
 | 
				
			||||||
 | 
					interface NoteDao {
 | 
				
			||||||
 | 
					    @Query("SELECT * FROM notes")
 | 
				
			||||||
 | 
					    fun getAll(): Flow<List<NoteEntity>>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Insert(onConflict = OnConflictStrategy.REPLACE)
 | 
				
			||||||
 | 
					    suspend fun insert(note: NoteEntity)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Delete
 | 
				
			||||||
 | 
					    suspend fun delete(note: NoteEntity)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,15 @@
 | 
				
			|||||||
 | 
					package come.stormborntales.notevault.data.local.entity
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import androidx.room.Entity
 | 
				
			||||||
 | 
					import androidx.room.PrimaryKey
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@Entity(tableName = "notes")
 | 
				
			||||||
 | 
					data class NoteEntity(
 | 
				
			||||||
 | 
					    @PrimaryKey(autoGenerate = true) val id: Int = 0,
 | 
				
			||||||
 | 
					    val title: String,
 | 
				
			||||||
 | 
					    val images: List<String>, // oder String + TypeConverter
 | 
				
			||||||
 | 
					    val composer: String?,
 | 
				
			||||||
 | 
					    val year: Int?,
 | 
				
			||||||
 | 
					    val genre: String?,
 | 
				
			||||||
 | 
					    val description: String?
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
@ -0,0 +1,12 @@
 | 
				
			|||||||
 | 
					package come.stormborntales.notevault.data.repository
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import come.stormborntales.notevault.data.local.dao.NoteDao
 | 
				
			||||||
 | 
					import come.stormborntales.notevault.data.local.entity.NoteEntity
 | 
				
			||||||
 | 
					import kotlinx.coroutines.flow.Flow
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class NoteRepository(private val dao: NoteDao) {
 | 
				
			||||||
 | 
					    val allNotes: Flow<List<NoteEntity>> = dao.getAll()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    suspend fun insert(note: NoteEntity) = dao.insert(note)
 | 
				
			||||||
 | 
					    suspend fun delete(note: NoteEntity) = dao.delete(note)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,62 @@
 | 
				
			|||||||
 | 
					package come.stormborntales.notevault.ui.viewmodel
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import android.content.Context
 | 
				
			||||||
 | 
					import android.net.Uri
 | 
				
			||||||
 | 
					import android.webkit.MimeTypeMap
 | 
				
			||||||
 | 
					import androidx.lifecycle.ViewModel
 | 
				
			||||||
 | 
					import androidx.lifecycle.asLiveData
 | 
				
			||||||
 | 
					import androidx.lifecycle.viewModelScope
 | 
				
			||||||
 | 
					import come.stormborntales.notevault.data.local.entity.NoteEntity
 | 
				
			||||||
 | 
					import come.stormborntales.notevault.data.repository.NoteRepository
 | 
				
			||||||
 | 
					import kotlinx.coroutines.Dispatchers
 | 
				
			||||||
 | 
					import kotlinx.coroutines.launch
 | 
				
			||||||
 | 
					import java.io.File
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class NoteViewModel(
 | 
				
			||||||
 | 
					    private val repository: NoteRepository,
 | 
				
			||||||
 | 
					) : ViewModel() {
 | 
				
			||||||
 | 
					    val notes = repository.allNotes.asLiveData()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fun addNote(context: Context, title: String, composer: String?, year: Int?, genre: String?, description: String?, selectedUris: List<Uri>, onDone:() -> Unit) {
 | 
				
			||||||
 | 
					        viewModelScope.launch(Dispatchers.IO) {
 | 
				
			||||||
 | 
					            val copiedUris = selectedUris.mapNotNull { uri ->
 | 
				
			||||||
 | 
					                try {
 | 
				
			||||||
 | 
					                    val inputStream = context.contentResolver.openInputStream(uri)
 | 
				
			||||||
 | 
					                    val extension = MimeTypeMap.getSingleton()
 | 
				
			||||||
 | 
					                        .getExtensionFromMimeType(context.contentResolver.getType(uri)) ?: "jpg"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    val outputFile = File(context.filesDir, "note_${System.currentTimeMillis()}.$extension")
 | 
				
			||||||
 | 
					                    inputStream?.use { input ->
 | 
				
			||||||
 | 
					                        outputFile.outputStream().use { output ->
 | 
				
			||||||
 | 
					                            input.copyTo(output)
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    Uri.fromFile(outputFile).toString() // speichern als String
 | 
				
			||||||
 | 
					                } catch (e: Exception) {
 | 
				
			||||||
 | 
					                    e.printStackTrace()
 | 
				
			||||||
 | 
					                    null
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (copiedUris.isNotEmpty()) {
 | 
				
			||||||
 | 
					                val note = NoteEntity(
 | 
				
			||||||
 | 
					                    title = title,
 | 
				
			||||||
 | 
					                    images = copiedUris, // muss als List<String> gespeichert sein
 | 
				
			||||||
 | 
					                    composer = composer,
 | 
				
			||||||
 | 
					                    year = year,
 | 
				
			||||||
 | 
					                    genre = genre,
 | 
				
			||||||
 | 
					                    description = description
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					                repository.insert(note)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            onDone()
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fun deleteNote(note: NoteEntity) {
 | 
				
			||||||
 | 
					        viewModelScope.launch {
 | 
				
			||||||
 | 
					            repository.delete(note)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					package come.stormborntales.notevault.ui.viewmodel
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import androidx.lifecycle.ViewModel
 | 
				
			||||||
 | 
					import androidx.lifecycle.ViewModelProvider
 | 
				
			||||||
 | 
					import come.stormborntales.notevault.data.repository.NoteRepository
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class NoteViewModelFactory(
 | 
				
			||||||
 | 
					    private val repository: NoteRepository
 | 
				
			||||||
 | 
					) : ViewModelProvider.Factory {
 | 
				
			||||||
 | 
					    override fun <T : ViewModel> create(modelClass: Class<T>): T {
 | 
				
			||||||
 | 
					        if (modelClass.isAssignableFrom(NoteViewModel::class.java)) {
 | 
				
			||||||
 | 
					            @Suppress("UNCHECKED_CAST")
 | 
				
			||||||
 | 
					            return NoteViewModel(repository) as T
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        throw IllegalArgumentException("Unknown ViewModel class")
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -10,13 +10,17 @@ lifecycleRuntimeKtx = "2.8.7"
 | 
				
			|||||||
activityCompose = "1.8.0"
 | 
					activityCompose = "1.8.0"
 | 
				
			||||||
composeBom = "2024.04.01"
 | 
					composeBom = "2024.04.01"
 | 
				
			||||||
navigationCompose = "2.8.9"
 | 
					navigationCompose = "2.8.9"
 | 
				
			||||||
 | 
					room = "2.7.1"
 | 
				
			||||||
 | 
					ksp="2.1.21-RC-2.0.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[libraries]
 | 
					[libraries]
 | 
				
			||||||
 | 
					lifecycle-livedata-ktx = "androidx.lifecycle:lifecycle-livedata-ktx:2.8.7"
 | 
				
			||||||
androidx-compose-bom-v20240100 = { module = "androidx.compose:compose-bom", version.ref = "composeBomVersion" }
 | 
					androidx-compose-bom-v20240100 = { module = "androidx.compose:compose-bom", version.ref = "composeBomVersion" }
 | 
				
			||||||
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
 | 
					androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
 | 
				
			||||||
androidx-foundation = { module = "androidx.compose.foundation:foundation" }
 | 
					androidx-foundation = { module = "androidx.compose.foundation:foundation" }
 | 
				
			||||||
androidx-lifecycle-viewmodel-compose = { module = "androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "lifecycleRuntimeKtx" }
 | 
					androidx-lifecycle-viewmodel-compose = { module = "androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "lifecycleRuntimeKtx" }
 | 
				
			||||||
androidx-navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "navigationCompose" }
 | 
					androidx-navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "navigationCompose" }
 | 
				
			||||||
 | 
					androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" }
 | 
				
			||||||
junit = { group = "junit", name = "junit", version.ref = "junit" }
 | 
					junit = { group = "junit", name = "junit", version.ref = "junit" }
 | 
				
			||||||
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
 | 
					androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
 | 
				
			||||||
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
 | 
					androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
 | 
				
			||||||
@ -30,9 +34,12 @@ 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-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
 | 
				
			||||||
androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
 | 
					androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
 | 
				
			||||||
androidx-material3 = { group = "androidx.compose.material3", name = "material3" }
 | 
					androidx-material3 = { group = "androidx.compose.material3", name = "material3" }
 | 
				
			||||||
 | 
					androidx-room-ktx = { module = "androidx.room:room-ktx", version.ref = "room" }
 | 
				
			||||||
 | 
					androidx-room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[plugins]
 | 
					[plugins]
 | 
				
			||||||
android-application = { id = "com.android.application", version.ref = "agp" }
 | 
					android-application = { id = "com.android.application", version.ref = "agp" }
 | 
				
			||||||
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
 | 
					kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
 | 
				
			||||||
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
 | 
					kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
 | 
				
			||||||
 | 
					ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user