Compare commits
3 Commits
646e2a5f1a
...
e70d8989f1
Author | SHA1 | Date | |
---|---|---|---|
|
e70d8989f1 | ||
|
3f661e8798 | ||
|
ba0cbcef09 |
3
.gitignore
vendored
3
.gitignore
vendored
@ -16,3 +16,6 @@ local.properties
|
|||||||
/music_database
|
/music_database
|
||||||
/music_database-shm
|
/music_database-shm
|
||||||
/music_database-wal
|
/music_database-wal
|
||||||
|
/note_database
|
||||||
|
/note_database-shm
|
||||||
|
/note_database-wal
|
||||||
|
71
.idea/dataSources.xml
Normal file
71
.idea/dataSources.xml
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
|
||||||
|
<data-source source="LOCAL" name="music_database" uuid="95a3c2ec-2c29-4336-900a-3993de90ae66">
|
||||||
|
<driver-ref>sqlite.xerial</driver-ref>
|
||||||
|
<synchronize>true</synchronize>
|
||||||
|
<jdbc-driver>org.sqlite.JDBC</jdbc-driver>
|
||||||
|
<jdbc-url>jdbc:sqlite:$USER_HOME$/.cache/JetBrains/IntelliJIdea2025.1/device-explorer/samsung SM-P610/_/data/data/com.stormtales.notevault/databases/music_database</jdbc-url>
|
||||||
|
<jdbc-additional-properties>
|
||||||
|
<property name="com.intellij.clouds.kubernetes.db.enabled" value="false" />
|
||||||
|
</jdbc-additional-properties>
|
||||||
|
<working-dir>$ProjectFileDir$</working-dir>
|
||||||
|
<libraries>
|
||||||
|
<library>
|
||||||
|
<url>file://$APPLICATION_CONFIG_DIR$/jdbc-drivers/Xerial SQLiteJDBC/3.45.1/org/xerial/sqlite-jdbc/3.45.1.0/sqlite-jdbc-3.45.1.0.jar</url>
|
||||||
|
</library>
|
||||||
|
<library>
|
||||||
|
<url>file://$APPLICATION_CONFIG_DIR$/jdbc-drivers/Xerial SQLiteJDBC/3.45.1/org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36.jar</url>
|
||||||
|
</library>
|
||||||
|
</libraries>
|
||||||
|
</data-source>
|
||||||
|
<data-source source="LOCAL" name="note_database" uuid="b3770d7c-0a73-40c6-aab8-010effaa19b6">
|
||||||
|
<driver-ref>sqlite.xerial</driver-ref>
|
||||||
|
<synchronize>true</synchronize>
|
||||||
|
<jdbc-driver>org.sqlite.JDBC</jdbc-driver>
|
||||||
|
<jdbc-url>jdbc:sqlite:$USER_HOME$/.cache/JetBrains/IntelliJIdea2025.1/device-explorer/samsung SM-P610/_/data/data/come.stormborntales.notevault/databases/note_database</jdbc-url>
|
||||||
|
<jdbc-additional-properties>
|
||||||
|
<property name="com.intellij.clouds.kubernetes.db.enabled" value="false" />
|
||||||
|
</jdbc-additional-properties>
|
||||||
|
<working-dir>$ProjectFileDir$</working-dir>
|
||||||
|
<libraries>
|
||||||
|
<library>
|
||||||
|
<url>file://$APPLICATION_CONFIG_DIR$/jdbc-drivers/Xerial SQLiteJDBC/3.45.1/org/xerial/sqlite-jdbc/3.45.1.0/sqlite-jdbc-3.45.1.0.jar</url>
|
||||||
|
</library>
|
||||||
|
<library>
|
||||||
|
<url>file://$APPLICATION_CONFIG_DIR$/jdbc-drivers/Xerial SQLiteJDBC/3.45.1/org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36.jar</url>
|
||||||
|
</library>
|
||||||
|
<library>
|
||||||
|
<url>file://$APPLICATION_CONFIG_DIR$/jdbc-drivers/Xerial SQLiteJDBC/3.45.1/org/xerial/sqlite-jdbc/3.45.1.0/sqlite-jdbc-3.45.1.0.jar</url>
|
||||||
|
</library>
|
||||||
|
<library>
|
||||||
|
<url>file://$APPLICATION_CONFIG_DIR$/jdbc-drivers/Xerial SQLiteJDBC/3.45.1/org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36.jar</url>
|
||||||
|
</library>
|
||||||
|
</libraries>
|
||||||
|
</data-source>
|
||||||
|
<data-source source="LOCAL" name="note_database [2]" uuid="ad94cfd9-e485-4151-8bf4-a080c51fa27c">
|
||||||
|
<driver-ref>sqlite.xerial</driver-ref>
|
||||||
|
<synchronize>true</synchronize>
|
||||||
|
<jdbc-driver>org.sqlite.JDBC</jdbc-driver>
|
||||||
|
<jdbc-url>jdbc:sqlite:$PROJECT_DIR$/note_database</jdbc-url>
|
||||||
|
<jdbc-additional-properties>
|
||||||
|
<property name="com.intellij.clouds.kubernetes.db.enabled" value="false" />
|
||||||
|
</jdbc-additional-properties>
|
||||||
|
<working-dir>$ProjectFileDir$</working-dir>
|
||||||
|
<libraries>
|
||||||
|
<library>
|
||||||
|
<url>file://$APPLICATION_CONFIG_DIR$/jdbc-drivers/Xerial SQLiteJDBC/3.45.1/org/xerial/sqlite-jdbc/3.45.1.0/sqlite-jdbc-3.45.1.0.jar</url>
|
||||||
|
</library>
|
||||||
|
<library>
|
||||||
|
<url>file://$APPLICATION_CONFIG_DIR$/jdbc-drivers/Xerial SQLiteJDBC/3.45.1/org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36.jar</url>
|
||||||
|
</library>
|
||||||
|
<library>
|
||||||
|
<url>file://$APPLICATION_CONFIG_DIR$/jdbc-drivers/Xerial SQLiteJDBC/3.45.1/org/xerial/sqlite-jdbc/3.45.1.0/sqlite-jdbc-3.45.1.0.jar</url>
|
||||||
|
</library>
|
||||||
|
<library>
|
||||||
|
<url>file://$APPLICATION_CONFIG_DIR$/jdbc-drivers/Xerial SQLiteJDBC/3.45.1/org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36.jar</url>
|
||||||
|
</library>
|
||||||
|
</libraries>
|
||||||
|
</data-source>
|
||||||
|
</component>
|
||||||
|
</project>
|
@ -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-29T17:33:41.575251940Z">
|
||||||
<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,10 @@ 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)
|
||||||
|
implementation(libs.compose.runtime.livedata)
|
||||||
|
|
||||||
|
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
|
||||||
@ -47,7 +57,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
|
|
||||||
// UI anzeigen
|
// UI anzeigen
|
||||||
MainScreen(
|
MainScreen(
|
||||||
notes = notes,
|
viewModel = viewModel,
|
||||||
onAddNoteClicked = {
|
onAddNoteClicked = {
|
||||||
imagePickerLauncher.launch(
|
imagePickerLauncher.launch(
|
||||||
arrayOf("image/*")
|
arrayOf("image/*")
|
||||||
@ -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,34 @@
|
|||||||
|
package come.stormborntales.notevault.data.local
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.util.Log
|
||||||
|
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
|
||||||
|
Log.d("AppDatabase", "Datenbank erstellt: ${instance.openHelper.writableDatabase}")
|
||||||
|
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)
|
||||||
|
}
|
@ -31,7 +31,7 @@ fun FullscreenImageViewer(
|
|||||||
HorizontalPager(state = pagerState) { page ->
|
HorizontalPager(state = pagerState) { page ->
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val imageBitmap = remember(images[page]) {
|
val imageBitmap = remember(images[page]) {
|
||||||
loadImageBitmap(context, images[page])
|
loadImageBitmap(context, images[page].toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
imageBitmap?.let {
|
imageBitmap?.let {
|
||||||
|
@ -15,6 +15,7 @@ import androidx.compose.material.icons.Icons
|
|||||||
import androidx.compose.material.icons.filled.Add
|
import androidx.compose.material.icons.filled.Add
|
||||||
import androidx.compose.material3.*
|
import androidx.compose.material3.*
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
|
import androidx.compose.runtime.livedata.observeAsState
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
@ -23,11 +24,15 @@ import androidx.compose.ui.graphics.asImageBitmap
|
|||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import come.stormborntales.notevault.FullscreenImageViewerActivity
|
import come.stormborntales.notevault.FullscreenImageViewerActivity
|
||||||
|
import come.stormborntales.notevault.data.local.entity.NoteEntity
|
||||||
import come.stormborntales.notevault.data.model.NoteEntry
|
import come.stormborntales.notevault.data.model.NoteEntry
|
||||||
|
import come.stormborntales.notevault.ui.viewmodel.NoteViewModel
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
|
import androidx.core.net.toUri
|
||||||
|
|
||||||
fun loadImageBitmap(context: Context, uri: Uri): ImageBitmap? {
|
fun loadImageBitmap(context: Context, uriString: String): ImageBitmap? {
|
||||||
return try {
|
return try {
|
||||||
|
val uri = uriString.toUri()
|
||||||
val inputStream: InputStream? = context.contentResolver.openInputStream(uri)
|
val inputStream: InputStream? = context.contentResolver.openInputStream(uri)
|
||||||
val bitmap = BitmapFactory.decodeStream(inputStream)
|
val bitmap = BitmapFactory.decodeStream(inputStream)
|
||||||
bitmap?.asImageBitmap()
|
bitmap?.asImageBitmap()
|
||||||
@ -38,7 +43,7 @@ fun loadImageBitmap(context: Context, uri: Uri): ImageBitmap? {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun NoteCard(note: NoteEntry) {
|
fun NoteCard(note: NoteEntity) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val imageBitmap = remember(note.images) {
|
val imageBitmap = remember(note.images) {
|
||||||
note.images.firstOrNull()?.let { loadImageBitmap(context, it) }
|
note.images.firstOrNull()?.let { loadImageBitmap(context, it) }
|
||||||
@ -100,8 +105,11 @@ fun NoteCard(note: NoteEntry) {
|
|||||||
) {
|
) {
|
||||||
OutlinedButton(
|
OutlinedButton(
|
||||||
onClick = {
|
onClick = {
|
||||||
|
val uris = ArrayList<Uri>();
|
||||||
|
note.images.forEach { uris.add(it.toUri()) }
|
||||||
|
|
||||||
val intent = Intent(context, FullscreenImageViewerActivity::class.java).apply {
|
val intent = Intent(context, FullscreenImageViewerActivity::class.java).apply {
|
||||||
putParcelableArrayListExtra("imageUris", ArrayList(note.images))
|
putParcelableArrayListExtra("imageUris", ArrayList(uris))
|
||||||
}
|
}
|
||||||
context.startActivity(intent)
|
context.startActivity(intent)
|
||||||
},
|
},
|
||||||
@ -135,12 +143,9 @@ fun NoteCard(note: NoteEntry) {
|
|||||||
@Composable
|
@Composable
|
||||||
fun MainScreen(
|
fun MainScreen(
|
||||||
onAddNoteClicked: () -> Unit, // Übergib hier deine Logik für den Import
|
onAddNoteClicked: () -> Unit, // Übergib hier deine Logik für den Import
|
||||||
notes: MutableList<NoteEntry>, // Liste der Notenbilder (hier als URI),
|
viewModel: NoteViewModel
|
||||||
) {
|
) {
|
||||||
val dummyNotes = notes
|
val notes by viewModel.notes.observeAsState(emptyList())
|
||||||
var noteToShow by remember { mutableStateOf<NoteEntry?>(null) }
|
|
||||||
// Hole den aktuellen Context
|
|
||||||
val context = LocalContext.current
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
TopAppBar(
|
TopAppBar(
|
||||||
@ -162,7 +167,7 @@ fun MainScreen(
|
|||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.padding(16.dp)
|
.padding(16.dp)
|
||||||
) {
|
) {
|
||||||
items(dummyNotes) { note ->
|
items(notes) { note ->
|
||||||
NoteCard(note = note)
|
NoteCard(note = note)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,65 @@
|
|||||||
|
package come.stormborntales.notevault.ui.viewmodel
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.net.Uri
|
||||||
|
import android.util.Log
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Log.d("NoteViewModel", "NoteEntityFile" + outputFile.absolutePath)
|
||||||
|
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,19 @@ 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"
|
||||||
|
compose = "1.6.0" # oder was immer deine aktuelle Compose-Version ist
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
|
compose-runtime-livedata = { group = "androidx.compose.runtime", name = "runtime-livedata", version.ref = "compose" }
|
||||||
|
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 +36,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