Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ dependencies {
implementation(libs.androidx.ui.graphics)
implementation(libs.androidx.ui.tooling.preview)
implementation(libs.androidx.material3)
implementation(libs.androidx.compose.material.icons.extended)
implementation(libs.coil.compose)
implementation(libs.koin.core)
implementation(libs.koin.android)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package app.plugbrain.android.ui.designsystem.components.listitem

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.unit.dp

@Composable
internal fun LeadingIcon(
modifier: Modifier = Modifier.Companion,
icon: ImageVector,
isSelected: Boolean,
) {
val tint =
if (isSelected) MaterialTheme.colorScheme.onPrimary else MaterialTheme.colorScheme.onSurfaceVariant
val background =
if (isSelected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.surfaceVariant
Icon(
imageVector = icon,
contentDescription = "",
tint = tint,
modifier = modifier
.background(
color = background,
shape = RoundedCornerShape(4.dp),
)
.size(40.dp)
.padding(8.dp),
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package app.plugbrain.android.ui.designsystem.components.listitem

import android.content.res.Configuration
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.rounded.TrendingUp
import androidx.compose.material.icons.rounded.LockOpen
import androidx.compose.material.icons.rounded.TrackChanges
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import app.plugbrain.android.ui.theme.MathlockAppTheme

@Composable
fun PlugInfoListItem(
title: String,
description: String,
icon: ImageVector,
) {
Row(
horizontalArrangement = Arrangement.spacedBy(24.dp),
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.background(MaterialTheme.colorScheme.surface),
) {
LeadingIcon(
icon = icon,
isSelected = false,
modifier = Modifier.align(Alignment.Top).padding(top = 3.dp),
)
Column(
verticalArrangement = Arrangement.spacedBy(4.dp),
modifier = Modifier.weight(1f),
) {
Text(title, style = MaterialTheme.typography.titleLarge, color = MaterialTheme.colorScheme.onSurface)
Text(description, style = MaterialTheme.typography.bodyLarge, color = MaterialTheme.colorScheme.onSurface)
}
}
}

@Preview(
name = "Light Mode",
showBackground = true,
uiMode = Configuration.UI_MODE_NIGHT_NO,
)
@Preview(
name = "Dark Mode",
showBackground = true,
uiMode = Configuration.UI_MODE_NIGHT_YES,
)
@Composable
private fun PermissionListItemPreview() {
MathlockAppTheme(dynamicColor = false) {
Column(
verticalArrangement = Arrangement.spacedBy(24.dp),
modifier = Modifier
.background(MaterialTheme.colorScheme.surface)
.padding(32.dp),
) {
PlugInfoListItem(
title = "Focus your attention",
description = "Spend less time on apps that distract you.",
icon = Icons.Rounded.TrackChanges,
)
PlugInfoListItem(
title = "Unlock with a challenge",
description = "Solve a quick math challenge to keep using the app.",
icon = Icons.Rounded.LockOpen,
)
PlugInfoListItem(
title = "Gets harder the longer you stay",
description = "Challenges increase in difficulty the longer you keep scrolling.",
icon = Icons.AutoMirrored.Rounded.TrendingUp,
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package app.plugbrain.android.ui.designsystem.components.listitem

import android.content.res.Configuration
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Search
import androidx.compose.material.icons.rounded.Layers
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import app.plugbrain.android.ui.theme.MathlockAppTheme

@Composable
fun PlugPermissionListItem(
title: String,
description: String,
icon: ImageVector,
isGranted: Boolean,
onClick: () -> Unit,
) {
Row(
horizontalArrangement = Arrangement.spacedBy(12.dp),
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.alpha(if (isGranted) 0.5f else 1f)
.border(
width = 1.dp,
color = MaterialTheme.colorScheme.outlineVariant,
shape = RoundedCornerShape(8.dp),
)
.background(MaterialTheme.colorScheme.surface)
.background(
color = if (isGranted) MaterialTheme.colorScheme.primary.copy(0.1f) else MaterialTheme.colorScheme.surface,
shape = RoundedCornerShape(8.dp),
)
.clickable(onClick = onClick)
.padding(vertical = 12.dp, horizontal = 16.dp),
) {
LeadingIcon(
icon = icon,
isSelected = isGranted,
modifier = Modifier.align(Alignment.Top).padding(top = 3.dp),
)
Column(
verticalArrangement = Arrangement.spacedBy(4.dp),
modifier = Modifier.weight(1f),
) {
Text(title, style = MaterialTheme.typography.titleMedium, color = MaterialTheme.colorScheme.onSurface)
Text(description, style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.onSurface)
}
TrailingIcon(isGranted)
}
}

@Preview(
name = "Light Mode",
showBackground = true,
uiMode = Configuration.UI_MODE_NIGHT_NO,
)
@Preview(
name = "Dark Mode",
showBackground = true,
uiMode = Configuration.UI_MODE_NIGHT_YES,
)
@Composable
private fun PermissionListItemPreview() {
MathlockAppTheme(dynamicColor = false) {
Column(
verticalArrangement = Arrangement.spacedBy(8.dp),
modifier = Modifier
.background(MaterialTheme.colorScheme.surface)
.padding(32.dp),
) {
PlugPermissionListItem(
title = "App Usage access",
description = "Lets PlugBrain track app usage so it can block distracting apps at the right time.",
isGranted = true,
icon = Icons.Filled.Search,
onClick = {},
)
PlugPermissionListItem(
title = "Display over other apps",
description = "Allows PlugBrain to display a challenge while you use a distracting app.",
isGranted = false,
icon = Icons.Rounded.Layers,
onClick = {},
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package app.plugbrain.android.ui.designsystem.components.listitem

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.rounded.KeyboardArrowRight
import androidx.compose.material.icons.rounded.Check
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp

@Composable
internal fun TrailingIcon(isSelected: Boolean) {
val tint =
if (isSelected) MaterialTheme.colorScheme.onPrimary else MaterialTheme.colorScheme.onSurfaceVariant
val background =
if (isSelected) MaterialTheme.colorScheme.primary else Color.Companion.Transparent
Icon(
imageVector = if (isSelected) Icons.Rounded.Check else Icons.AutoMirrored.Rounded.KeyboardArrowRight,
contentDescription = "",
tint = tint,
modifier = Modifier.Companion
.background(color = background, shape = RoundedCornerShape(50))
.size(24.dp)
.then(if (isSelected) Modifier.Companion.padding(4.dp) else Modifier.Companion),
)
}
6 changes: 5 additions & 1 deletion app/src/main/java/app/plugbrain/android/ui/theme/Theme.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@ private val DarkColorScheme =
background = Neutral900,
error = Error600,
outline = Neutral200,
outlineVariant = Neutral500,
surfaceVariant = Neutral500,
onSurfaceVariant = Neutral300,
tertiary = Success300,
onTertiary = White,
)

private val LightColorScheme =
Expand All @@ -37,9 +39,11 @@ private val LightColorScheme =
background = White,
error = Error500,
outline = Neutral300,
outlineVariant = Neutral200,
surfaceVariant = Neutral100,
onSurfaceVariant = Neutral300,
onSurfaceVariant = Neutral400,
tertiary = Success500,
onTertiary = White,
)

@Composable
Expand Down
14 changes: 14 additions & 0 deletions app/src/main/java/app/plugbrain/android/ui/theme/Type.kt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ val Typography =
),

titleLarge = TextStyle(
fontFamily = SoraFontFamily,
fontWeight = FontWeight.SemiBold,
fontSize = 16.sp,
lineHeight = 22.sp,
),

titleMedium = TextStyle(
fontFamily = SoraFontFamily,
fontWeight = FontWeight.SemiBold,
fontSize = 14.sp,
Expand All @@ -53,6 +60,13 @@ val Typography =
lineHeight = 22.sp,
),

bodyMedium = TextStyle(
fontFamily = SoraFontFamily,
fontWeight = FontWeight.Normal,
fontSize = 14.sp,
lineHeight = 17.sp,
),

labelLarge = TextStyle(
fontFamily = SoraFontFamily,
fontWeight = FontWeight.SemiBold,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package app.plugbrain.android.screenshots

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.rounded.TrendingUp
import androidx.compose.material.icons.rounded.LockOpen
import androidx.compose.material.icons.rounded.TrackChanges
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import app.cash.paparazzi.DeviceConfig
import app.cash.paparazzi.Paparazzi
import app.plugbrain.android.ui.designsystem.components.listitem.PlugInfoListItem
import app.plugbrain.android.ui.theme.MathlockAppTheme
import org.junit.Rule
import org.junit.Test

class InfoListItemScreenshotTest {
@get:Rule
val paparazzi =
Paparazzi(
deviceConfig = DeviceConfig.PIXEL_5,
)

@Test
fun permissionListItemGrantedTest() {
paparazzi.snapshot {
infoItemTest()
}
}

@Test
fun permissionListItemDarkModeTest() {
paparazzi.snapshot {
infoItemTest(darkTheme = true)
}
}

@Composable
private fun infoItemTest(darkTheme: Boolean = false) {
MathlockAppTheme(dynamicColor = false, darkTheme = darkTheme) {
Column(
verticalArrangement = Arrangement.spacedBy(24.dp),
modifier =
Modifier
.background(MaterialTheme.colorScheme.surface)
.padding(32.dp),
) {
PlugInfoListItem(
title = "Focus your attention",
description = "Spend less time on apps that distract you.",
icon = Icons.Rounded.TrackChanges,
)
PlugInfoListItem(
title = "Unlock with a challenge",
description = "Solve a quick math challenge to keep using the app.",
icon = Icons.Rounded.LockOpen,
)
PlugInfoListItem(
title = "Gets harder the longer you stay",
description = "Challenges increase in difficulty the longer you keep scrolling.",
icon = Icons.AutoMirrored.Rounded.TrendingUp,
)
}
}
}
}
Loading
Loading