diff --git a/app/src/main/java/dev/msfjarvis/lobsters/ui/posts/Header.kt b/app/src/main/java/dev/msfjarvis/lobsters/ui/posts/Header.kt new file mode 100644 index 00000000..0cf2ef0c --- /dev/null +++ b/app/src/main/java/dev/msfjarvis/lobsters/ui/posts/Header.kt @@ -0,0 +1,40 @@ +package dev.msfjarvis.lobsters.ui.posts + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import dev.msfjarvis.lobsters.ui.theme.LobstersTheme +import dev.msfjarvis.lobsters.ui.theme.titleColor +import java.time.Month +import java.util.Locale +import java.time.format.TextStyle as JTextStyle + +@Composable +fun MonthHeader(month: Month) { + Box( + Modifier + .fillMaxWidth() + .wrapContentHeight() + ) { + Text( + text = month.getDisplayName(JTextStyle.FULL, Locale.getDefault()), + style = MaterialTheme.typography.h4.copy(color = titleColor), + modifier = Modifier.padding(horizontal = 12.dp), + ) + } +} + +@Preview +@Composable +fun MonthHeaderPreview() { + LobstersTheme { + MonthHeader(month = Month.JULY) + } +} diff --git a/app/src/main/java/dev/msfjarvis/lobsters/ui/posts/SavedPosts.kt b/app/src/main/java/dev/msfjarvis/lobsters/ui/posts/SavedPosts.kt index d52999d3..d88df6a0 100644 --- a/app/src/main/java/dev/msfjarvis/lobsters/ui/posts/SavedPosts.kt +++ b/app/src/main/java/dev/msfjarvis/lobsters/ui/posts/SavedPosts.kt @@ -1,5 +1,6 @@ package dev.msfjarvis.lobsters.ui.posts +import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.rememberLazyListState @@ -7,7 +8,9 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import dev.msfjarvis.lobsters.data.local.LobstersPost import dev.msfjarvis.lobsters.ui.urllauncher.LocalUrlLauncher +import dev.msfjarvis.lobsters.util.asZonedDateTime +@OptIn(ExperimentalFoundationApi::class) @Composable fun SavedPosts( posts: List, @@ -22,16 +25,22 @@ fun SavedPosts( } else { LazyColumn( state = listState, - modifier = Modifier.then(modifier) + modifier = Modifier.then(modifier), ) { - items(posts) { item -> - LobstersItem( - post = item, - isSaved = true, - onClick = { urlLauncher.launch(item.url.ifEmpty { item.comments_url }) }, - onLongClick = { urlLauncher.launch(item.comments_url) }, - onSaveButtonClick = { saveAction.invoke(item) }, - ) + val grouped = posts.groupBy { it.created_at.asZonedDateTime().month } + grouped.forEach { (month, posts) -> + stickyHeader { + MonthHeader(month = month) + } + items(posts) { item -> + LobstersItem( + post = item, + isSaved = true, + onClick = { urlLauncher.launch(item.url.ifEmpty { item.comments_url }) }, + onLongClick = { urlLauncher.launch(item.comments_url) }, + onSaveButtonClick = { saveAction.invoke(item) }, + ) + } } } } diff --git a/app/src/main/java/dev/msfjarvis/lobsters/util/DateExtensions.kt b/app/src/main/java/dev/msfjarvis/lobsters/util/DateExtensions.kt new file mode 100644 index 00000000..0d1bd89d --- /dev/null +++ b/app/src/main/java/dev/msfjarvis/lobsters/util/DateExtensions.kt @@ -0,0 +1,16 @@ +package dev.msfjarvis.lobsters.util + +import java.text.SimpleDateFormat +import java.time.ZoneId +import java.time.ZonedDateTime +import java.util.Locale + +/** + * Parses a given [String] into a [ZonedDateTime]. This method only works on dates in the format + * returned by the Lobsters API, and is not a general purpose parsing solution. + */ +fun String.asZonedDateTime(): ZonedDateTime { + val sdf = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.US) + val date = checkNotNull(sdf.parse(this)) + return date.toInstant().atZone(ZoneId.systemDefault()) +} diff --git a/app/src/test/java/dev/msfjarvis/lobsters/util/DateExtensionsTest.kt b/app/src/test/java/dev/msfjarvis/lobsters/util/DateExtensionsTest.kt new file mode 100644 index 00000000..1a649f1b --- /dev/null +++ b/app/src/test/java/dev/msfjarvis/lobsters/util/DateExtensionsTest.kt @@ -0,0 +1,13 @@ +package dev.msfjarvis.lobsters.util + +import java.time.Month +import org.junit.Assert.* +import org.junit.Test + +class DateExtensionsTest { + @Test + fun `parses date correctly`() { + val datetime = "2021-02-15T21:16:02.000-06:00".asZonedDateTime() + assertEquals(Month.FEBRUARY, datetime.month) + } +}