nextNoteVault #23

Merged
sebastian merged 57 commits from nextNoteVault into master 2025-05-10 06:23:23 +00:00
8 changed files with 101 additions and 42 deletions
Showing only changes of commit f20c8f0096 - Show all commits

View File

@ -40,6 +40,9 @@
<inspection_tool class="PreviewMultipleParameterProviders" enabled="true" level="ERROR" enabled_by_default="true"> <inspection_tool class="PreviewMultipleParameterProviders" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" /> <option name="composableFile" value="true" />
</inspection_tool> </inspection_tool>
<inspection_tool class="PreviewParameterProviderOnFirstParameter" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewPickerAnnotation" enabled="true" level="ERROR" enabled_by_default="true"> <inspection_tool class="PreviewPickerAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" /> <option name="composableFile" value="true" />
</inspection_tool> </inspection_tool>

View File

@ -2,27 +2,23 @@ package come.stormborntales.notevault
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.webkit.MimeTypeMap import android.util.Log
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
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 androidx.lifecycle.viewmodel.compose.viewModel
import come.stormborntales.notevault.data.local.AppDatabase import come.stormborntales.notevault.data.local.AppDatabase
import come.stormborntales.notevault.data.model.NoteEntry import come.stormborntales.notevault.data.local.entity.NoteEntity
import come.stormborntales.notevault.data.repository.NoteRepository 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.NoteViewModel
import come.stormborntales.notevault.ui.viewmodel.NoteViewModelFactory import come.stormborntales.notevault.ui.viewmodel.NoteViewModelFactory
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.File
import java.io.InputStream
class MainActivity : ComponentActivity() { class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
@ -35,11 +31,6 @@ class MainActivity : ComponentActivity() {
setContent { setContent {
NoteVaultTheme { NoteVaultTheme {
val viewModel: NoteViewModel = viewModel(factory = viewModelFactory) val viewModel: NoteViewModel = viewModel(factory = viewModelFactory)
val context = LocalContext.current
// Globale Notenliste
val notes = remember { mutableStateListOf<NoteEntry>() }
// Bildauswahl + Dialog-States // Bildauswahl + Dialog-States
var selectedUris by remember { mutableStateOf<List<Uri>>(emptyList()) } var selectedUris by remember { mutableStateOf<List<Uri>>(emptyList()) }
var showDialog by remember { mutableStateOf(false) } var showDialog by remember { mutableStateOf(false) }
@ -55,6 +46,15 @@ class MainActivity : ComponentActivity() {
} }
) )
var noteToEdit by remember { mutableStateOf<NoteEntity?>(null) }
// Dialog anzeigen
val openDialog: (NoteEntity?) -> Unit = { note ->
Log.d("EditNote", "NoteEntity: " + note?.title)
noteToEdit = note
showDialog = true
}
// UI anzeigen // UI anzeigen
MainScreen( MainScreen(
viewModel = viewModel, viewModel = viewModel,
@ -62,7 +62,8 @@ class MainActivity : ComponentActivity() {
imagePickerLauncher.launch( imagePickerLauncher.launch(
arrayOf("image/*") arrayOf("image/*")
) )
} },
onEditNote = openDialog
) )
// Dialog bei Bedarf // Dialog bei Bedarf
@ -72,17 +73,34 @@ class MainActivity : ComponentActivity() {
AddNoteDialog( AddNoteDialog(
onDismiss = { showDialog = false }, onDismiss = { showDialog = false },
onSave = { title, composer, year, genre, description -> onSave = { title, composer, year, genre, description ->
viewModel.addNote( if(noteToEdit == null) {
context = context, viewModel.addNote(
title = title, context = context,
composer = composer, title = title,
year = year, composer = composer,
genre = genre, year = year,
description = description, genre = genre,
selectedUris = selectedUris, description = description,
onDone = { showDialog = false } selectedUris = selectedUris,
) onDone = { showDialog = false }
} )
} else {
viewModel.updateNote(
editedNote = noteToEdit!!,
updatedTitle = title,
updatedComposer = composer,
updatedYear = year,
updatedGenre = genre,
updatedDescription = description,
onDone = { showDialog = false }
)
}
},
initialTitle = noteToEdit?.title ?: "",
initialComposer = noteToEdit?.composer,
initialYear = noteToEdit?.year,
initialGenre = noteToEdit?.genre,
initialDescription = noteToEdit?.description
) )
} }
} }

View File

@ -5,6 +5,7 @@ import androidx.room.Delete
import androidx.room.Insert import androidx.room.Insert
import androidx.room.OnConflictStrategy import androidx.room.OnConflictStrategy
import androidx.room.Query import androidx.room.Query
import androidx.room.Update
import come.stormborntales.notevault.data.local.entity.NoteEntity import come.stormborntales.notevault.data.local.entity.NoteEntity
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
@ -18,4 +19,7 @@ interface NoteDao {
@Delete @Delete
suspend fun delete(note: NoteEntity) suspend fun delete(note: NoteEntity)
@Update
suspend fun update(note: NoteEntity)
} }

View File

@ -6,11 +6,11 @@ import androidx.room.PrimaryKey
@Entity(tableName = "notes") @Entity(tableName = "notes")
data class NoteEntity( data class NoteEntity(
@PrimaryKey(autoGenerate = true) val id: Int = 0, @PrimaryKey(autoGenerate = true) val id: Int = 0,
val title: String, var title: String,
val images: List<String>, // oder String + TypeConverter val images: List<String>, // oder String + TypeConverter
val composer: String?, var composer: String?,
val year: Int?, var year: Int?,
val genre: String?, var genre: String?,
val description: String?, var description: String?,
val imagePreview: String val imagePreview: String
) )

View File

@ -9,4 +9,6 @@ class NoteRepository(private val dao: NoteDao) {
suspend fun insert(note: NoteEntity) = dao.insert(note) suspend fun insert(note: NoteEntity) = dao.insert(note)
suspend fun delete(note: NoteEntity) = dao.delete(note) suspend fun delete(note: NoteEntity) = dao.delete(note)
suspend fun update(note: NoteEntity) = dao.update(note);
} }

View File

@ -14,15 +14,21 @@ import androidx.compose.ui.unit.dp
@Composable @Composable
fun AddNoteDialog( fun AddNoteDialog(
onDismiss: () -> Unit, onDismiss: () -> Unit,
onSave: (title: String, composer: String?, year: Int?, genre: String?, description: String?) -> Unit onSave: (title: String, composer: String?, year: Int?, genre: String?, description: String?) -> Unit,
initialTitle: String = "",
initialComposer: String? = null,
initialYear: Int? = null,
initialGenre: String? = null,
initialDescription: String? = null
) { ) {
var title by remember { mutableStateOf("") } var title by remember { mutableStateOf(initialTitle) }
var composer by remember { mutableStateOf("") } var composer by remember { mutableStateOf(initialComposer ?: "") }
var yearText by remember { mutableStateOf("") } var yearText by remember { mutableStateOf(initialYear?.toString() ?: "") }
var genre by remember { mutableStateOf("") } var genre by remember { mutableStateOf(initialGenre ?: "") }
var description by remember { mutableStateOf("") } var description by remember { mutableStateOf(initialDescription ?: "") }
var showTitleError by remember { mutableStateOf(false) } var showTitleError by remember { mutableStateOf(false) }
AlertDialog( AlertDialog(
onDismissRequest = onDismiss, onDismissRequest = onDismiss,
confirmButton = { confirmButton = {

View File

@ -6,6 +6,7 @@ import android.graphics.BitmapFactory
import android.graphics.ImageDecoder import android.graphics.ImageDecoder
import android.media.Image import android.media.Image
import android.net.Uri import android.net.Uri
import android.util.Log
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
@ -45,7 +46,7 @@ fun loadImageBitmap(context: Context, uriString: String): ImageBitmap? {
} }
@Composable @Composable
fun NoteCard(note: NoteEntity, onDeleteNote: (NoteEntity) -> Unit) { fun NoteCard(note: NoteEntity, onDeleteNote: (NoteEntity) -> Unit, onEditNote: (NoteEntity) -> Unit) {
val context = LocalContext.current val context = LocalContext.current
@ -71,7 +72,7 @@ fun NoteCard(note: NoteEntity, onDeleteNote: (NoteEntity) -> Unit) {
modifier = Modifier modifier = Modifier
.weight(1f) .weight(1f)
.align(Alignment.CenterVertically) .align(Alignment.CenterVertically)
.padding(start=16.dp) .padding(start = 16.dp)
) { ) {
Text( Text(
text = note.title, text = note.title,
@ -116,7 +117,10 @@ fun NoteCard(note: NoteEntity, onDeleteNote: (NoteEntity) -> Unit) {
Text("Anzeigen", style = MaterialTheme.typography.labelLarge) Text("Anzeigen", style = MaterialTheme.typography.labelLarge)
} }
OutlinedButton( OutlinedButton(
onClick = { /* TODO */ }, onClick = {
onEditNote(note)
Log.d("EditNote", "on Edit Note!")
},
contentPadding = PaddingValues(horizontal = 12.dp, vertical = 4.dp) contentPadding = PaddingValues(horizontal = 12.dp, vertical = 4.dp)
) { ) {
Text("Bearbeiten", style = MaterialTheme.typography.labelLarge) Text("Bearbeiten", style = MaterialTheme.typography.labelLarge)
@ -143,7 +147,8 @@ fun NoteCard(note: NoteEntity, onDeleteNote: (NoteEntity) -> Unit) {
@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
viewModel: NoteViewModel viewModel: NoteViewModel,
onEditNote: (NoteEntity) -> Unit
) { ) {
val notes by viewModel.notes.observeAsState(emptyList()) val notes by viewModel.notes.observeAsState(emptyList())
Scaffold( Scaffold(
@ -168,9 +173,9 @@ fun MainScreen(
.padding(16.dp) .padding(16.dp)
) { ) {
items(notes) { note -> items(notes) { note ->
NoteCard(note = note, onDeleteNote = {noteEntity -> NoteCard(note = note, onDeleteNote = { noteEntity ->
viewModel.deleteNote(noteEntity) viewModel.deleteNote(noteEntity)
}) }, onEditNote = onEditNote)
} }
} }
} }

View File

@ -14,7 +14,6 @@ import come.stormborntales.notevault.data.repository.NoteRepository
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.io.File import java.io.File
import java.io.InputStream
import androidx.core.graphics.scale import androidx.core.graphics.scale
class NoteViewModel( class NoteViewModel(
@ -86,4 +85,26 @@ class NoteViewModel(
repository.delete(note) repository.delete(note)
} }
} }
fun updateNote(
editedNote: NoteEntity,
updatedTitle: String,
updatedComposer: String?,
updatedYear: Int?,
updatedGenre: String?,
updatedDescription: String?,
onDone: () -> Unit
) {
viewModelScope.launch {
editedNote.title = updatedTitle
editedNote.year = updatedYear;
editedNote.composer = updatedComposer
editedNote.genre = updatedGenre
editedNote.description = updatedDescription
repository.update(editedNote)
onDone()
}
}
} }