From fb70cd5e31c9a44c77347f93f5db5e8d9685833e Mon Sep 17 00:00:00 2001 From: Adit Lal Date: Sun, 16 Jun 2024 12:49:42 +0530 Subject: [PATCH] Adds Note UI --- .../kotlin/com/app/academy/HomeScreen.kt | 15 +++--- .../com/app/academy/components/NoteItems.kt | 29 ++++++++++ .../app/academy/components/NoteListCard.kt | 54 +++++++++++++++++++ .../components/SwipeableNoteListCard.kt | 46 ++++++++++++++++ .../kotlin/app/architect/notes/model/Note.kt | 24 +++++++++ 5 files changed, 160 insertions(+), 8 deletions(-) create mode 100644 composeApp/src/commonMain/kotlin/com/app/academy/components/NoteItems.kt create mode 100644 composeApp/src/commonMain/kotlin/com/app/academy/components/NoteListCard.kt create mode 100644 composeApp/src/commonMain/kotlin/com/app/academy/components/SwipeableNoteListCard.kt diff --git a/composeApp/src/commonMain/kotlin/com/app/academy/HomeScreen.kt b/composeApp/src/commonMain/kotlin/com/app/academy/HomeScreen.kt index 9dd6b6e..96e9c5d 100644 --- a/composeApp/src/commonMain/kotlin/com/app/academy/HomeScreen.kt +++ b/composeApp/src/commonMain/kotlin/com/app/academy/HomeScreen.kt @@ -1,21 +1,20 @@ package com.app.academy -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.material.Text +import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import app.architect.notes.model.dummyNotes import cafe.adriel.voyager.core.screen.Screen +import com.app.academy.components.NoteItems object HomeScreen : Screen { @Composable override fun Content() { - Box( - modifier = Modifier.fillMaxSize(), - contentAlignment = Alignment.Center - ) { - Text(text = "To be built") + LazyColumn(Modifier.fillMaxSize()) { + NoteItems(dummyNotes, onClick = {}) { + //onDismissed + } } } } diff --git a/composeApp/src/commonMain/kotlin/com/app/academy/components/NoteItems.kt b/composeApp/src/commonMain/kotlin/com/app/academy/components/NoteItems.kt new file mode 100644 index 0000000..b788fed --- /dev/null +++ b/composeApp/src/commonMain/kotlin/com/app/academy/components/NoteItems.kt @@ -0,0 +1,29 @@ +package com.app.academy.components + +import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyListScope +import androidx.compose.foundation.lazy.items +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import app.architect.notes.model.Note + +@OptIn(ExperimentalFoundationApi::class) +fun LazyListScope.NoteItems( + notes: List, + onClick: (Note) -> Unit, + onDismissed: (Note) -> Unit +) { + items(items = notes, key = { it.id }) { + SwipeableNoteListCard( + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 8.dp, horizontal = 16.dp) + .animateItemPlacement(), + savedNote = it, + onClick = { onClick(it) }, + onDismissed = { onDismissed(it) } + ) + } +} diff --git a/composeApp/src/commonMain/kotlin/com/app/academy/components/NoteListCard.kt b/composeApp/src/commonMain/kotlin/com/app/academy/components/NoteListCard.kt new file mode 100644 index 0000000..562cfa2 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/com/app/academy/components/NoteListCard.kt @@ -0,0 +1,54 @@ +package com.app.academy.components + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.LazyRow +import androidx.compose.material.Card +import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import app.architect.notes.model.Note + +/** + * A composable that displays the information of a [Note], in a card. Some of the contents + * might get truncated if the content of the [Note] is too long. Mainly meant to be used in + * a list, such as a [LazyColumn] or a [LazyRow]. + * + * @param modifier The modifier to be applied to the card. + * @param savedNote The note to be displayed. + * @param onClick The click listener for the card. + */ +@OptIn(ExperimentalMaterialApi::class) +@Composable +fun NoteListCard( + modifier: Modifier = Modifier, + savedNote: Note, + onClick: () -> Unit +) { + Card(modifier = modifier, onClick = onClick) { + Column( + modifier = Modifier.padding(16.dp), + verticalArrangement = Arrangement.spacedBy(8.dp) + ) { + Text( + text = savedNote.title, + style = MaterialTheme.typography.h6, + fontWeight = FontWeight.Bold, + maxLines = 3 + ) + Text( + text = savedNote.content, + maxLines = 3, + minLines = 3, + overflow = TextOverflow.Ellipsis + ) + } + } +} diff --git a/composeApp/src/commonMain/kotlin/com/app/academy/components/SwipeableNoteListCard.kt b/composeApp/src/commonMain/kotlin/com/app/academy/components/SwipeableNoteListCard.kt new file mode 100644 index 0000000..9f597fa --- /dev/null +++ b/composeApp/src/commonMain/kotlin/com/app/academy/components/SwipeableNoteListCard.kt @@ -0,0 +1,46 @@ +package com.app.academy.components + +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.material.DismissDirection +import androidx.compose.material.DismissState +import androidx.compose.material.DismissValue +import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material.SwipeToDismiss +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import app.architect.notes.model.Note + +@OptIn(ExperimentalMaterialApi::class) +@Composable +fun SwipeableNoteListCard( + modifier: Modifier = Modifier, + onClick: () -> Unit, + onDismissed: () -> Unit, + savedNote: Note, +) { + val dismissState = remember(savedNote) { + DismissState( + initialValue = DismissValue.Default, + confirmStateChange = { + if (it != DismissValue.DismissedToStart) return@DismissState false + onDismissed() + true + } + ) + } + + SwipeToDismiss( + modifier = modifier, + state = dismissState, + background = {}, + dismissContent = { + NoteListCard( + modifier = Modifier.fillMaxWidth(), + savedNote = savedNote, + onClick = onClick + ) + }, + directions = setOf(DismissDirection.EndToStart) + ) +} diff --git a/shared/src/commonMain/kotlin/app/architect/notes/model/Note.kt b/shared/src/commonMain/kotlin/app/architect/notes/model/Note.kt index 14ac8c5..7d800da 100644 --- a/shared/src/commonMain/kotlin/app/architect/notes/model/Note.kt +++ b/shared/src/commonMain/kotlin/app/architect/notes/model/Note.kt @@ -43,3 +43,27 @@ fun Note.toSavedNoteEntity(): SavedNoteEntity { isDeleted = if (this.isDeleted) 1 else 0 ) } + +val dummyNotes = listOf( + Note( + id = "id1", + title = "Dummy note 1", + content = "This is a test note 1", + createdAtTimestampMillis = 0L, + isDeleted = false + ), + Note( + id = "id2", + title = "Dummy note 2", + content = "This is a test note 2", + createdAtTimestampMillis = 1L, + isDeleted = false + ), + Note( + id = "id3", + title = "Dummy note 3", + content = "This is a test note 3", + createdAtTimestampMillis = 2L, + isDeleted = false + ) +)