UPD: Display Notes and Collections as beautiful grid

This commit is contained in:
sebastian 2025-05-10 13:34:36 +02:00
parent dd7e9dce65
commit 234a5a7a60
3 changed files with 97 additions and 38 deletions

View File

@ -63,4 +63,5 @@ dependencies {
implementation(libs.compose.runtime.livedata) implementation(libs.compose.runtime.livedata)
implementation(libs.coil.compose) implementation(libs.coil.compose)
ksp(libs.androidx.room.compiler) ksp(libs.androidx.room.compiler)
implementation(libs.androidx.material.icons.extended)
} }

View File

@ -2,20 +2,30 @@ package come.stormborntales.notevault.ui.screens
import android.util.Log import android.util.Log
import androidx.activity.compose.BackHandler import androidx.activity.compose.BackHandler
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentWidth import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.Folder
import androidx.compose.material3.AlertDialog import androidx.compose.material3.AlertDialog
import androidx.compose.material3.DropdownMenu import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.DropdownMenuItem
@ -35,12 +45,18 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue 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.draw.clip
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.ViewModelStoreOwner import androidx.lifecycle.ViewModelStoreOwner
import androidx.lifecycle.viewmodel.compose.LocalViewModelStoreOwner import androidx.lifecycle.viewmodel.compose.LocalViewModelStoreOwner
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import coil.compose.AsyncImage
import come.stormborntales.notevault.data.local.AppDatabase import come.stormborntales.notevault.data.local.AppDatabase
import come.stormborntales.notevault.data.local.entity.NoteCollection import come.stormborntales.notevault.data.local.entity.NoteCollection
import come.stormborntales.notevault.data.local.entity.NoteEntity
import come.stormborntales.notevault.data.repository.CollectionRepository import come.stormborntales.notevault.data.repository.CollectionRepository
import come.stormborntales.notevault.data.repository.NoteRepository import come.stormborntales.notevault.data.repository.NoteRepository
import come.stormborntales.notevault.ui.viewmodel.NoteBrowserViewModel import come.stormborntales.notevault.ui.viewmodel.NoteBrowserViewModel
@ -142,6 +158,78 @@ private fun BreadcrumbItem(label: String, onClick: () -> Unit) {
} }
} }
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun NoteGrid(
modifier: Modifier = Modifier,
collections: List<NoteCollection>,
notes: List<NoteEntity>,
onCollectionClick: (NoteCollection) -> Unit,
onNoteClick: (NoteEntity) -> Unit
) {
val columns = 2 // Anzahl Spalten, ggf. responsiv machen
LazyVerticalGrid(
modifier = modifier.fillMaxSize(),
columns = GridCells.Fixed(columns),
contentPadding = PaddingValues(8.dp),
verticalArrangement = Arrangement.spacedBy(12.dp),
horizontalArrangement = Arrangement.spacedBy(12.dp)
) {
items(collections) { collection ->
Column(
modifier = Modifier
.clip(RoundedCornerShape(12.dp))
.background(MaterialTheme.colorScheme.surfaceVariant)
.clickable { onCollectionClick(collection) }
.padding(12.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Icon(
imageVector = Icons.Filled.Folder,
contentDescription = "Ordner",
tint = MaterialTheme.colorScheme.primary,
modifier = Modifier.size(64.dp)
)
Text(
text = collection.name,
style = MaterialTheme.typography.bodyMedium,
textAlign = TextAlign.Center,
maxLines = 2,
overflow = TextOverflow.Ellipsis,
modifier = Modifier.padding(top = 8.dp)
)
}
}
items(notes) { note ->
Column(
modifier = Modifier
.clip(RoundedCornerShape(12.dp))
.background(MaterialTheme.colorScheme.surfaceVariant)
.clickable { onNoteClick(note) }
.padding(12.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
AsyncImage(
model = note.imagePreview,
contentDescription = "Noten-Vorschau",
modifier = Modifier
.size(64.dp)
.clip(RoundedCornerShape(8.dp)),
contentScale = ContentScale.Crop
)
Text(
text = note.title,
style = MaterialTheme.typography.bodyMedium,
textAlign = TextAlign.Center,
maxLines = 2,
overflow = TextOverflow.Ellipsis,
modifier = Modifier.padding(top = 8.dp)
)
}
}
}
}
@Composable @Composable
fun NotesScreen( fun NotesScreen(
collectionRepository: CollectionRepository, collectionRepository: CollectionRepository,
@ -212,45 +300,13 @@ fun NotesScreen(
} }
) )
LazyColumn { NoteGrid(
item { collections = collections,
Text( notes = notes,
"Ordner", onCollectionClick = { viewModel.loadContentForParent(it.id, it) },
style = MaterialTheme.typography.titleMedium, onNoteClick = { /* TODO: Öffnen oder Bearbeiten */ }
modifier = Modifier.padding(16.dp)
) )
}
items(collections) { collection ->
ListItem(
headlineContent = { Text(collection.name) },
modifier = Modifier
.clickable {
viewModel.loadContentForParent(collection.id, collection)
}
.padding(horizontal = 8.dp)
)
}
item {
Spacer(modifier = Modifier.height(16.dp))
Text(
"Noten",
style = MaterialTheme.typography.titleMedium,
modifier = Modifier.padding(16.dp)
)
}
items(notes) { note ->
ListItem(
headlineContent = { Text(note.title) },
supportingContent = {
note.composer?.let { Text(it) }
},
modifier = Modifier.padding(horizontal = 8.dp)
)
}
}
} }

View File

@ -9,12 +9,14 @@ espressoCore = "3.6.1"
lifecycleRuntimeKtx = "2.8.7" lifecycleRuntimeKtx = "2.8.7"
activityCompose = "1.8.0" activityCompose = "1.8.0"
composeBom = "2024.04.01" composeBom = "2024.04.01"
materialIconsExtended = "1.7.8"
navigationCompose = "2.8.9" navigationCompose = "2.8.9"
room = "2.7.1" room = "2.7.1"
ksp="2.1.21-RC-2.0.0" ksp="2.1.21-RC-2.0.0"
compose = "1.6.0" # oder was immer deine aktuelle Compose-Version ist compose = "1.6.0" # oder was immer deine aktuelle Compose-Version ist
[libraries] [libraries]
androidx-material-icons-extended = { module = "androidx.compose.material:material-icons-extended", version.ref = "materialIconsExtended" }
coil-compose = { group = "io.coil-kt", name = "coil-compose", version = "2.5.0" } # oder aktueller coil-compose = { group = "io.coil-kt", name = "coil-compose", version = "2.5.0" } # oder aktueller
compose-runtime-livedata = { group = "androidx.compose.runtime", name = "runtime-livedata", version.ref = "compose" } compose-runtime-livedata = { group = "androidx.compose.runtime", name = "runtime-livedata", version.ref = "compose" }
lifecycle-livedata-ktx = "androidx.lifecycle:lifecycle-livedata-ktx:2.8.7" lifecycle-livedata-ktx = "androidx.lifecycle:lifecycle-livedata-ktx:2.8.7"