Add sticky headers to saved posts

Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
This commit is contained in:
Harsh Shandilya 2021-02-27 17:33:42 +05:30
parent 1733b3124d
commit 639f814ef8
No known key found for this signature in database
GPG key ID: 366D7BBAD1031E80
4 changed files with 87 additions and 9 deletions

View file

@ -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)
}
}

View file

@ -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<LobstersPost>,
@ -22,8 +25,13 @@ fun SavedPosts(
} else {
LazyColumn(
state = listState,
modifier = Modifier.then(modifier)
modifier = Modifier.then(modifier),
) {
val grouped = posts.groupBy { it.created_at.asZonedDateTime().month }
grouped.forEach { (month, posts) ->
stickyHeader {
MonthHeader(month = month)
}
items(posts) { item ->
LobstersItem(
post = item,
@ -35,4 +43,5 @@ fun SavedPosts(
}
}
}
}
}

View file

@ -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())
}

View file

@ -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)
}
}