all: reorganize some composables

This commit is contained in:
Harsh Shandilya 2022-06-27 22:42:19 +05:30
parent 6aff88774b
commit b282e47213
No known key found for this signature in database
GPG key ID: 366D7BBAD1031E80
14 changed files with 56 additions and 52 deletions

View file

@ -48,6 +48,7 @@ dependencies {
implementation(libs.material.motion.navigation) implementation(libs.material.motion.navigation)
implementation(libs.sqldelight.extensions.coroutines) implementation(libs.sqldelight.extensions.coroutines)
implementation(libs.kotlin.coroutines.core) implementation(libs.kotlin.coroutines.core)
implementation(libs.kotlinx.datetime)
implementation(libs.kotlinx.serialization.json) implementation(libs.kotlinx.serialization.json)
implementation(libs.retrofit.kotlinxSerializationConverter) implementation(libs.retrofit.kotlinxSerializationConverter)
implementation(libs.androidx.work.runtime.ktx) implementation(libs.androidx.work.runtime.ktx)

View file

@ -29,7 +29,6 @@ import androidx.navigation.navDeepLink
import androidx.paging.compose.collectAsLazyPagingItems import androidx.paging.compose.collectAsLazyPagingItems
import com.google.accompanist.systemuicontroller.rememberSystemUiController import com.google.accompanist.systemuicontroller.rememberSystemUiController
import dev.msfjarvis.claw.android.R import dev.msfjarvis.claw.android.R
import dev.msfjarvis.claw.android.ui.decorations.ClawAppBar
import dev.msfjarvis.claw.android.ui.decorations.ClawNavigationBar import dev.msfjarvis.claw.android.ui.decorations.ClawNavigationBar
import dev.msfjarvis.claw.android.ui.decorations.NavigationItem import dev.msfjarvis.claw.android.ui.decorations.NavigationItem
import dev.msfjarvis.claw.android.ui.lists.DatabasePosts import dev.msfjarvis.claw.android.ui.lists.DatabasePosts
@ -42,6 +41,8 @@ import dev.msfjarvis.claw.common.comments.HTMLConverter
import dev.msfjarvis.claw.common.comments.LocalHTMLConverter import dev.msfjarvis.claw.common.comments.LocalHTMLConverter
import dev.msfjarvis.claw.common.res.ClawIcons import dev.msfjarvis.claw.common.res.ClawIcons
import dev.msfjarvis.claw.common.theme.LobstersTheme import dev.msfjarvis.claw.common.theme.LobstersTheme
import dev.msfjarvis.claw.common.ui.decorations.ClawAppBar
import dev.msfjarvis.claw.common.ui.surfaceColorAtNavigationBarElevation
import dev.msfjarvis.claw.common.urllauncher.UrlLauncher import dev.msfjarvis.claw.common.urllauncher.UrlLauncher
import dev.msfjarvis.claw.common.user.UserProfile import dev.msfjarvis.claw.common.user.UserProfile
import kotlinx.coroutines.launch import kotlinx.coroutines.launch

View file

@ -11,16 +11,12 @@ import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.ColorScheme import androidx.compose.material3.ColorScheme
import androidx.compose.material3.LocalAbsoluteTonalElevation
import androidx.compose.material3.dynamicDarkColorScheme import androidx.compose.material3.dynamicDarkColorScheme
import androidx.compose.material3.dynamicLightColorScheme import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.State import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.compositeOver
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController import androidx.navigation.NavController
import dev.msfjarvis.claw.android.ui.navigation.Destinations import dev.msfjarvis.claw.android.ui.navigation.Destinations
import dev.msfjarvis.claw.android.viewmodel.ClawViewModel import dev.msfjarvis.claw.android.viewmodel.ClawViewModel
@ -29,11 +25,10 @@ import dev.msfjarvis.claw.common.theme.DarkThemeColors
import dev.msfjarvis.claw.common.theme.LightThemeColors import dev.msfjarvis.claw.common.theme.LightThemeColors
import dev.msfjarvis.claw.common.urllauncher.UrlLauncher import dev.msfjarvis.claw.common.urllauncher.UrlLauncher
import dev.msfjarvis.claw.database.local.SavedPost import dev.msfjarvis.claw.database.local.SavedPost
import java.text.SimpleDateFormat import kotlinx.datetime.Instant
import java.time.ZoneId import kotlinx.datetime.LocalDateTime
import java.time.ZonedDateTime import kotlinx.datetime.TimeZone
import java.util.Locale import kotlinx.datetime.toLocalDateTime
import kotlin.math.ln
private const val AnimationDuration = 100 private const val AnimationDuration = 100
@ -54,13 +49,11 @@ fun slideOutAnimation(): ExitTransition {
} }
/** /**
* Parses a given [String] into a [ZonedDateTime]. This method only works on dates in the format * Parses a given [String] into a [LocalDateTime]. This method is only intended to be used for dates
* returned by the Lobsters API, and is not a general purpose parsing solution. * in the format returned by the Lobsters API, and is not a general purpose parsing solution.
*/ */
fun String.asZonedDateTime(): ZonedDateTime { fun String.toLocalDateTime(): LocalDateTime {
val sdf = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.US) return Instant.parse(this).toLocalDateTime(TimeZone.currentSystemDefault())
val date = checkNotNull(sdf.parse(this))
return date.toInstant().atZone(ZoneId.systemDefault())
} }
// The destination needs to be tracked like this rather than used directly since // The destination needs to be tracked like this rather than used directly since
@ -124,21 +117,3 @@ fun rememberPostActions(
} }
} }
} }
/**
* Returns the [ColorScheme.surface] color with an alpha of the [ColorScheme.primary] color overlaid
* on top of it. Computes the surface tonal color at different elevation levels e.g. surface1
* through surface5.
*
* Stolen from AndroidX, keep in sync when upgrading Compose. This version is hard-coded to
* replicate the logic used by the Material3 NavigationBar to determine its surface color.
* https://github.com/androidx/androidx/blob/74d3510b608c3cc26b9cf9be8d15a6a6c26192c2/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/ColorScheme.kt#L453-L466
*/
@Composable
fun ColorScheme.surfaceColorAtNavigationBarElevation(): Color {
// Absolute tonal elevation + NavigationBarTokens.ContainerElevation
val elevation = LocalAbsoluteTonalElevation.current + 3.0.dp
if (elevation == 0.dp) return surface
val alpha = ((4.5f * ln(elevation.value + 1)) + 2f) / 100f
return primary.copy(alpha = alpha).compositeOver(surface)
}

View file

@ -6,11 +6,11 @@ import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import dev.msfjarvis.claw.android.ui.decorations.MonthHeader
import dev.msfjarvis.claw.common.posts.PostActions import dev.msfjarvis.claw.common.posts.PostActions
import dev.msfjarvis.claw.common.ui.Divider import dev.msfjarvis.claw.common.ui.Divider
import dev.msfjarvis.claw.common.ui.decorations.MonthHeader
import dev.msfjarvis.claw.database.local.SavedPost import dev.msfjarvis.claw.database.local.SavedPost
import java.time.Month import kotlinx.datetime.Month
@OptIn(ExperimentalFoundationApi::class) @OptIn(ExperimentalFoundationApi::class)
@Composable @Composable

View file

@ -6,16 +6,16 @@ import androidx.paging.Pager
import androidx.paging.PagingConfig import androidx.paging.PagingConfig
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import dev.msfjarvis.claw.android.paging.LobstersPagingSource import dev.msfjarvis.claw.android.paging.LobstersPagingSource
import dev.msfjarvis.claw.android.ui.asZonedDateTime import dev.msfjarvis.claw.android.ui.toLocalDateTime
import dev.msfjarvis.claw.api.LobstersApi import dev.msfjarvis.claw.api.LobstersApi
import dev.msfjarvis.claw.database.local.SavedPost import dev.msfjarvis.claw.database.local.SavedPost
import java.time.Month
import javax.inject.Inject import javax.inject.Inject
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import kotlinx.datetime.Month
@HiltViewModel @HiltViewModel
class ClawViewModel class ClawViewModel
@ -48,8 +48,8 @@ constructor(
get() = savedPostsFlow.map(::mapSavedPosts) get() = savedPostsFlow.map(::mapSavedPosts)
private fun mapSavedPosts(items: List<SavedPost>): Map<Month, List<SavedPost>> { private fun mapSavedPosts(items: List<SavedPost>): Map<Month, List<SavedPost>> {
val sorted = items.sortedByDescending { post -> post.createdAt.asZonedDateTime() } val sorted = items.sortedByDescending { post -> post.createdAt.toLocalDateTime() }
return sorted.groupBy { post -> post.createdAt.asZonedDateTime().month } return sorted.groupBy { post -> post.createdAt.toLocalDateTime().month }
} }
suspend fun isPostSaved(post: SavedPost): Boolean { suspend fun isPostSaved(post: SavedPost): Boolean {

View file

@ -36,6 +36,7 @@ kotlin {
api(projects.model) api(projects.model)
api(libs.napier) api(libs.napier)
implementation(libs.kotlin.coroutines.core) implementation(libs.kotlin.coroutines.core)
implementation(libs.kotlinx.datetime)
implementation(libs.compose.richtext.markdown) implementation(libs.compose.richtext.markdown)
implementation(libs.compose.richtext.material3) implementation(libs.compose.richtext.material3)
implementation(libs.compose.richtext.ui) implementation(libs.compose.richtext.ui)

View file

@ -1,4 +1,4 @@
package dev.msfjarvis.claw.android.ui.decorations package dev.msfjarvis.claw.common.ui.decorations
import androidx.compose.material3.SmallTopAppBar import androidx.compose.material3.SmallTopAppBar
import androidx.compose.material3.TopAppBarDefaults import androidx.compose.material3.TopAppBarDefaults

View file

@ -1,4 +1,4 @@
package dev.msfjarvis.claw.android.ui.decorations package dev.msfjarvis.claw.common.ui.decorations
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
@ -9,11 +9,11 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.text.capitalize
import androidx.compose.ui.text.intl.Locale
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import dev.msfjarvis.claw.android.ui.surfaceColorAtNavigationBarElevation import dev.msfjarvis.claw.common.ui.surfaceColorAtNavigationBarElevation
import java.time.Month import kotlinx.datetime.Month
import java.time.format.TextStyle as JTextStyle
import java.util.Locale
@Composable @Composable
fun MonthHeader(month: Month) { fun MonthHeader(month: Month) {
@ -23,7 +23,7 @@ fun MonthHeader(month: Month) {
.background(MaterialTheme.colorScheme.surfaceColorAtNavigationBarElevation()) .background(MaterialTheme.colorScheme.surfaceColorAtNavigationBarElevation())
) { ) {
Text( Text(
text = month.getDisplayName(JTextStyle.FULL, Locale.getDefault()), text = month.name.lowercase().capitalize(Locale.current),
style = MaterialTheme.typography.headlineSmall, style = MaterialTheme.typography.headlineSmall,
modifier = Modifier.padding(horizontal = 12.dp, vertical = 12.dp), modifier = Modifier.padding(horizontal = 12.dp, vertical = 12.dp),
) )

View file

@ -0,0 +1,27 @@
package dev.msfjarvis.claw.common.ui
import androidx.compose.material3.ColorScheme
import androidx.compose.material3.LocalAbsoluteTonalElevation
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.compositeOver
import androidx.compose.ui.unit.dp
import kotlin.math.ln
/**
* Returns the [ColorScheme.surface] color with an alpha of the [ColorScheme.primary] color overlaid
* on top of it. Computes the surface tonal color at different elevation levels e.g. surface1
* through surface5.
*
* Stolen from AndroidX, keep in sync when upgrading Compose. This version is hard-coded to
* replicate the logic used by the Material3 NavigationBar to determine its surface color.
* https://github.com/androidx/androidx/blob/74d3510b608c3cc26b9cf9be8d15a6a6c26192c2/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/ColorScheme.kt#L453-L466
*/
@Composable
fun ColorScheme.surfaceColorAtNavigationBarElevation(): Color {
// Absolute tonal elevation + NavigationBarTokens.ContainerElevation
val elevation = LocalAbsoluteTonalElevation.current + 3.0.dp
if (elevation == 0.dp) return surface
val alpha = ((4.5f * ln(elevation.value + 1)) + 2f) / 100f
return primary.copy(alpha = alpha).compositeOver(surface)
}

View file

@ -53,6 +53,7 @@ dagger-hilt-compiler = { module = "com.google.dagger:hilt-compiler", version.ref
javapoet = "com.squareup:javapoet:1.13.0" javapoet = "com.squareup:javapoet:1.13.0"
kamel-image = "com.alialbaali.kamel:kamel-image:0.3.0" kamel-image = "com.alialbaali.kamel:kamel-image:0.3.0"
kotlin-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" } kotlin-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" }
kotlinx-datetime = "org.jetbrains.kotlinx:kotlinx-datetime:0.4.0"
kotlinx-serialization-core = { module = "org.jetbrains.kotlinx:kotlinx-serialization-core", version.ref = "serialization" } kotlinx-serialization-core = { module = "org.jetbrains.kotlinx:kotlinx-serialization-core", version.ref = "serialization" }
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "serialization" } kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "serialization" }
material_motion-core = { module = "io.github.fornewid:material-motion-compose-core", version.ref = "material_motion" } material_motion-core = { module = "io.github.fornewid:material-motion-compose-core", version.ref = "material_motion" }

View file

@ -15,10 +15,8 @@ android {
dependencies { dependencies {
testImplementation(kotlin("test-junit")) testImplementation(kotlin("test-junit"))
testImplementation(projects.android) testImplementation(libs.kotlinx.datetime)
testImplementation(projects.common) testImplementation(projects.common)
testImplementation(projects.model)
testImplementation(projects.database)
} }
tasks.withType<Test>().configureEach { tasks.withType<Test>().configureEach {

View file

@ -2,10 +2,10 @@ package dev.msfjarvis.claw.android.tests
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import app.cash.paparazzi.Paparazzi import app.cash.paparazzi.Paparazzi
import dev.msfjarvis.claw.android.ui.decorations.MonthHeader
import dev.msfjarvis.claw.common.theme.DarkThemeColors import dev.msfjarvis.claw.common.theme.DarkThemeColors
import dev.msfjarvis.claw.common.theme.LightThemeColors import dev.msfjarvis.claw.common.theme.LightThemeColors
import java.time.Month import dev.msfjarvis.claw.common.ui.decorations.MonthHeader
import kotlinx.datetime.Month
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.3 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

Before After
Before After