mirror of
https://github.com/msfjarvis/compose-lobsters
synced 2025-08-14 14:07:05 +05:30
all: reorganize some composables
This commit is contained in:
parent
6aff88774b
commit
b282e47213
14 changed files with 56 additions and 52 deletions
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
|
||||||
}
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
|
@ -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),
|
||||||
)
|
)
|
|
@ -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)
|
||||||
|
}
|
|
@ -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" }
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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 |
Binary file not shown.
Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 8.3 KiB |
Loading…
Add table
Add a link
Reference in a new issue