feat: Add a custom color theme feature
This commit is contained in:
80
app/src/main/java/org/nsh07/pomodoro/ui/ClickableListItem.kt
Normal file
80
app/src/main/java/org/nsh07/pomodoro/ui/ClickableListItem.kt
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
package org.nsh07.pomodoro.ui
|
||||||
|
|
||||||
|
import androidx.compose.animation.core.animateDpAsState
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
|
import androidx.compose.foundation.interaction.collectIsPressedAsState
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||||
|
import androidx.compose.material3.ListItem
|
||||||
|
import androidx.compose.material3.ListItemColors
|
||||||
|
import androidx.compose.material3.ListItemDefaults
|
||||||
|
import androidx.compose.material3.MaterialTheme.motionScheme
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.unit.Dp
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
|
||||||
|
@Composable
|
||||||
|
fun ClickableListItem(
|
||||||
|
headlineContent: @Composable (() -> Unit),
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
overlineContent: @Composable (() -> Unit)? = null,
|
||||||
|
supportingContent: @Composable (() -> Unit)? = null,
|
||||||
|
leadingContent: @Composable (() -> Unit)? = null,
|
||||||
|
trailingContent: @Composable (() -> Unit)? = null,
|
||||||
|
colors: ListItemColors = ListItemDefaults.colors(),
|
||||||
|
tonalElevation: Dp = ListItemDefaults.Elevation,
|
||||||
|
shadowElevation: Dp = ListItemDefaults.Elevation,
|
||||||
|
items: Int,
|
||||||
|
index: Int,
|
||||||
|
onClick: () -> Unit
|
||||||
|
) {
|
||||||
|
val interactionSource = remember { MutableInteractionSource() }
|
||||||
|
val isPressed by interactionSource.collectIsPressedAsState()
|
||||||
|
|
||||||
|
val top by animateDpAsState(
|
||||||
|
if (isPressed) 40.dp
|
||||||
|
else {
|
||||||
|
if (items == 1 || index == 0) 20.dp
|
||||||
|
else 4.dp
|
||||||
|
},
|
||||||
|
motionScheme.fastSpatialSpec()
|
||||||
|
)
|
||||||
|
val bottom by animateDpAsState(
|
||||||
|
if (isPressed) 40.dp
|
||||||
|
else {
|
||||||
|
if (items == 1 || index == items - 1) 20.dp
|
||||||
|
else 4.dp
|
||||||
|
},
|
||||||
|
motionScheme.fastSpatialSpec()
|
||||||
|
)
|
||||||
|
|
||||||
|
ListItem(
|
||||||
|
headlineContent = headlineContent,
|
||||||
|
modifier = modifier
|
||||||
|
.clip(
|
||||||
|
RoundedCornerShape(
|
||||||
|
topStart = top,
|
||||||
|
topEnd = top,
|
||||||
|
bottomStart = bottom,
|
||||||
|
bottomEnd = bottom
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.clickable(
|
||||||
|
onClick = onClick,
|
||||||
|
interactionSource = interactionSource,
|
||||||
|
),
|
||||||
|
overlineContent = overlineContent,
|
||||||
|
supportingContent = supportingContent,
|
||||||
|
leadingContent = leadingContent,
|
||||||
|
trailingContent = trailingContent,
|
||||||
|
colors = colors,
|
||||||
|
tonalElevation = tonalElevation,
|
||||||
|
shadowElevation = shadowElevation
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,157 @@
|
|||||||
|
package org.nsh07.pomodoro.ui.settingsScreen
|
||||||
|
|
||||||
|
import androidx.compose.animation.AnimatedContent
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.foundation.layout.wrapContentHeight
|
||||||
|
import androidx.compose.foundation.layout.wrapContentWidth
|
||||||
|
import androidx.compose.material3.AlertDialogDefaults
|
||||||
|
import androidx.compose.material3.BasicAlertDialog
|
||||||
|
import androidx.compose.material3.ButtonDefaults
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.IconButton
|
||||||
|
import androidx.compose.material3.IconButtonDefaults
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.MaterialTheme.colorScheme
|
||||||
|
import androidx.compose.material3.MaterialTheme.shapes
|
||||||
|
import androidx.compose.material3.Surface
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TextButton
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.util.fastForEach
|
||||||
|
import org.nsh07.pomodoro.R
|
||||||
|
import org.nsh07.pomodoro.ui.theme.TomatoTheme
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
|
||||||
|
@Composable
|
||||||
|
fun ColorPickerButton(
|
||||||
|
color: Color,
|
||||||
|
isSelected: Boolean,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
onClick: () -> Unit
|
||||||
|
) {
|
||||||
|
IconButton(
|
||||||
|
shapes = IconButtonDefaults.shapes(),
|
||||||
|
colors = IconButtonDefaults.iconButtonColors(containerColor = color),
|
||||||
|
modifier = modifier.size(48.dp),
|
||||||
|
onClick = onClick
|
||||||
|
) {
|
||||||
|
AnimatedContent(isSelected) { isSelected ->
|
||||||
|
when (isSelected) {
|
||||||
|
true -> Icon(
|
||||||
|
painterResource(R.drawable.check),
|
||||||
|
tint = Color.Black,
|
||||||
|
contentDescription = null
|
||||||
|
)
|
||||||
|
|
||||||
|
else ->
|
||||||
|
if (color == Color.White) Icon(
|
||||||
|
painterResource(R.drawable.colors),
|
||||||
|
tint = Color.Black,
|
||||||
|
contentDescription = null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
|
||||||
|
@Composable
|
||||||
|
fun ColorSchemePickerDialog(
|
||||||
|
currentColor: Color,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
setShowDialog: (Boolean) -> Unit,
|
||||||
|
onColorChange: (Color) -> Unit,
|
||||||
|
) {
|
||||||
|
val colorSchemes = listOf(
|
||||||
|
Color(0xfffeb4a7), Color(0xffffb3c0), Color(0xfffcaaff), Color(0xffb9c3ff),
|
||||||
|
Color(0xff62d3ff), Color(0xff44d9f1), Color(0xff52dbc9), Color(0xff78dd77),
|
||||||
|
Color(0xff9fd75c), Color(0xffc1d02d), Color(0xfffabd00), Color(0xffffb86e),
|
||||||
|
Color.White
|
||||||
|
)
|
||||||
|
|
||||||
|
BasicAlertDialog(
|
||||||
|
onDismissRequest = { setShowDialog(false) },
|
||||||
|
modifier = modifier
|
||||||
|
) {
|
||||||
|
Surface(
|
||||||
|
modifier = Modifier
|
||||||
|
.wrapContentWidth()
|
||||||
|
.wrapContentHeight(),
|
||||||
|
color = colorScheme.surfaceContainer,
|
||||||
|
shape = shapes.extraLarge,
|
||||||
|
tonalElevation = AlertDialogDefaults.TonalElevation
|
||||||
|
) {
|
||||||
|
Column(modifier = Modifier.padding(24.dp)) {
|
||||||
|
Text(
|
||||||
|
text = "Choose color scheme",
|
||||||
|
style = MaterialTheme.typography.headlineSmall
|
||||||
|
)
|
||||||
|
|
||||||
|
Spacer(Modifier.height(16.dp))
|
||||||
|
|
||||||
|
Column(Modifier.align(Alignment.CenterHorizontally)) {
|
||||||
|
(0..11 step 4).forEach {
|
||||||
|
Row {
|
||||||
|
colorSchemes.slice(it..it + 3).fastForEach { color ->
|
||||||
|
ColorPickerButton(
|
||||||
|
color,
|
||||||
|
color == currentColor,
|
||||||
|
modifier = Modifier.padding(4.dp)
|
||||||
|
) {
|
||||||
|
onColorChange(color)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ColorPickerButton(
|
||||||
|
colorSchemes.last(),
|
||||||
|
colorSchemes.last() == currentColor,
|
||||||
|
modifier = Modifier.padding(4.dp)
|
||||||
|
) {
|
||||||
|
onColorChange(colorSchemes.last())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(Modifier.height(24.dp))
|
||||||
|
|
||||||
|
TextButton(
|
||||||
|
shapes = ButtonDefaults.shapes(),
|
||||||
|
onClick = { setShowDialog(false) },
|
||||||
|
modifier = Modifier.align(Alignment.End)
|
||||||
|
) {
|
||||||
|
Text("Ok")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preview
|
||||||
|
@Composable
|
||||||
|
fun ColorPickerDialogPreview() {
|
||||||
|
var currentColor by remember { mutableStateOf(Color(0xfffeb4a7)) }
|
||||||
|
TomatoTheme(darkTheme = true) {
|
||||||
|
ColorSchemePickerDialog(
|
||||||
|
currentColor,
|
||||||
|
setShowDialog = {},
|
||||||
|
onColorChange = { currentColor = it }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025 Nishant Mishra
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.nsh07.pomodoro.ui.settingsScreen
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.MaterialTheme.colorScheme
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import org.nsh07.pomodoro.R
|
||||||
|
import org.nsh07.pomodoro.ui.ClickableListItem
|
||||||
|
import org.nsh07.pomodoro.ui.theme.CustomColors.listItemColors
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ColorSchemePickerListItem(
|
||||||
|
color: Color,
|
||||||
|
items: Int,
|
||||||
|
index: Int,
|
||||||
|
onColorChange: (Color) -> Unit,
|
||||||
|
modifier: Modifier = Modifier
|
||||||
|
) {
|
||||||
|
var showDialog by rememberSaveable { mutableStateOf(false) }
|
||||||
|
|
||||||
|
if (showDialog) {
|
||||||
|
ColorSchemePickerDialog(
|
||||||
|
currentColor = color,
|
||||||
|
setShowDialog = { showDialog = it },
|
||||||
|
onColorChange = onColorChange
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
ClickableListItem(
|
||||||
|
leadingContent = {
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(R.drawable.palette),
|
||||||
|
contentDescription = null,
|
||||||
|
tint = colorScheme.primary
|
||||||
|
)
|
||||||
|
},
|
||||||
|
headlineContent = { Text("Color scheme") },
|
||||||
|
supportingContent = {
|
||||||
|
Text(
|
||||||
|
if (color == Color.White) "Dynamic"
|
||||||
|
else "Color"
|
||||||
|
)
|
||||||
|
},
|
||||||
|
colors = listItemColors,
|
||||||
|
items = items,
|
||||||
|
index = index,
|
||||||
|
modifier = modifier.fillMaxWidth()
|
||||||
|
) { showDialog = true }
|
||||||
|
}
|
||||||
@@ -53,6 +53,7 @@ import androidx.compose.material3.TopAppBar
|
|||||||
import androidx.compose.material3.TopAppBarDefaults
|
import androidx.compose.material3.TopAppBarDefaults
|
||||||
import androidx.compose.material3.rememberSliderState
|
import androidx.compose.material3.rememberSliderState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
@@ -139,6 +140,7 @@ fun SettingsScreenRoot(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
onThemeChange = viewModel::saveTheme,
|
onThemeChange = viewModel::saveTheme,
|
||||||
|
onColorSchemeChange = viewModel::saveColorScheme,
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -159,6 +161,7 @@ private fun SettingsScreen(
|
|||||||
onBlackThemeChange: (Boolean) -> Unit,
|
onBlackThemeChange: (Boolean) -> Unit,
|
||||||
onAlarmSoundChanged: (Uri?) -> Unit,
|
onAlarmSoundChanged: (Uri?) -> Unit,
|
||||||
onThemeChange: (String) -> Unit,
|
onThemeChange: (String) -> Unit,
|
||||||
|
onColorSchemeChange: (Color) -> Unit,
|
||||||
modifier: Modifier = Modifier
|
modifier: Modifier = Modifier
|
||||||
) {
|
) {
|
||||||
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
|
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
|
||||||
@@ -185,6 +188,12 @@ private fun SettingsScreen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
var alarmName by remember { mutableStateOf("") }
|
||||||
|
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
alarmName = RingtoneManager.getRingtone(context, alarmSound.toUri())
|
||||||
|
?.getTitle(context) ?: ""
|
||||||
|
}
|
||||||
|
|
||||||
val ringtonePickerLauncher = rememberLauncherForActivityResult(
|
val ringtonePickerLauncher = rememberLauncherForActivityResult(
|
||||||
contract = ActivityResultContracts.StartActivityForResult()
|
contract = ActivityResultContracts.StartActivityForResult()
|
||||||
@@ -358,25 +367,11 @@ private fun SettingsScreen(
|
|||||||
item { Spacer(Modifier.height(12.dp)) }
|
item { Spacer(Modifier.height(12.dp)) }
|
||||||
|
|
||||||
item {
|
item {
|
||||||
ListItem(
|
ColorSchemePickerListItem(
|
||||||
leadingContent = {
|
color = preferencesState.colorScheme.toColor(),
|
||||||
Icon(
|
items = 3,
|
||||||
painter = painterResource(R.drawable.palette),
|
index = 0,
|
||||||
contentDescription = null,
|
onColorChange = onColorSchemeChange
|
||||||
tint = colorScheme.primary
|
|
||||||
)
|
|
||||||
},
|
|
||||||
headlineContent = { Text("Color scheme") },
|
|
||||||
supportingContent = {
|
|
||||||
Text(
|
|
||||||
if (preferencesState.colorScheme.toColor() == Color.White) "Dynamic"
|
|
||||||
else "Color"
|
|
||||||
)
|
|
||||||
},
|
|
||||||
colors = listItemColors,
|
|
||||||
modifier = Modifier
|
|
||||||
.clip(topListItemShape)
|
|
||||||
.clickable(onClick = {})
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
item {
|
item {
|
||||||
@@ -385,6 +380,8 @@ private fun SettingsScreen(
|
|||||||
themeMap = themeMap,
|
themeMap = themeMap,
|
||||||
reverseThemeMap = reverseThemeMap,
|
reverseThemeMap = reverseThemeMap,
|
||||||
onThemeChange = onThemeChange,
|
onThemeChange = onThemeChange,
|
||||||
|
items = 3,
|
||||||
|
index = 1,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.clip(middleListItemShape)
|
.clip(middleListItemShape)
|
||||||
)
|
)
|
||||||
@@ -432,14 +429,7 @@ private fun SettingsScreen(
|
|||||||
Icon(painterResource(R.drawable.alarm), null)
|
Icon(painterResource(R.drawable.alarm), null)
|
||||||
},
|
},
|
||||||
headlineContent = { Text("Alarm sound") },
|
headlineContent = { Text("Alarm sound") },
|
||||||
supportingContent = {
|
supportingContent = { Text(alarmName) },
|
||||||
Text(
|
|
||||||
remember(alarmSound) {
|
|
||||||
RingtoneManager.getRingtone(context, alarmSound.toUri())
|
|
||||||
?.getTitle(context) ?: ""
|
|
||||||
}
|
|
||||||
)
|
|
||||||
},
|
|
||||||
colors = listItemColors,
|
colors = listItemColors,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.clip(topListItemShape)
|
.clip(topListItemShape)
|
||||||
@@ -542,6 +532,7 @@ fun SettingsScreenPreview() {
|
|||||||
onBlackThemeChange = {},
|
onBlackThemeChange = {},
|
||||||
onAlarmSoundChanged = {},
|
onAlarmSoundChanged = {},
|
||||||
onThemeChange = {},
|
onThemeChange = {},
|
||||||
|
onColorSchemeChange = {},
|
||||||
modifier = Modifier.fillMaxSize()
|
modifier = Modifier.fillMaxSize()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,10 +7,8 @@
|
|||||||
|
|
||||||
package org.nsh07.pomodoro.ui.settingsScreen
|
package org.nsh07.pomodoro.ui.settingsScreen
|
||||||
|
|
||||||
import androidx.compose.foundation.clickable
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.ListItem
|
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
@@ -19,6 +17,7 @@ import androidx.compose.runtime.saveable.rememberSaveable
|
|||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import org.nsh07.pomodoro.ui.ClickableListItem
|
||||||
import org.nsh07.pomodoro.ui.theme.CustomColors.listItemColors
|
import org.nsh07.pomodoro.ui.theme.CustomColors.listItemColors
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@@ -26,6 +25,8 @@ fun ThemePickerListItem(
|
|||||||
theme: String,
|
theme: String,
|
||||||
themeMap: Map<String, Pair<Int, String>>,
|
themeMap: Map<String, Pair<Int, String>>,
|
||||||
reverseThemeMap: Map<String, String>,
|
reverseThemeMap: Map<String, String>,
|
||||||
|
items: Int,
|
||||||
|
index: Int,
|
||||||
onThemeChange: (String) -> Unit,
|
onThemeChange: (String) -> Unit,
|
||||||
modifier: Modifier = Modifier
|
modifier: Modifier = Modifier
|
||||||
) {
|
) {
|
||||||
@@ -41,7 +42,7 @@ fun ThemePickerListItem(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
ListItem(
|
ClickableListItem(
|
||||||
leadingContent = {
|
leadingContent = {
|
||||||
Icon(
|
Icon(
|
||||||
painter = painterResource(themeMap[theme]!!.first),
|
painter = painterResource(themeMap[theme]!!.first),
|
||||||
@@ -53,8 +54,8 @@ fun ThemePickerListItem(
|
|||||||
Text(themeMap[theme]!!.second)
|
Text(themeMap[theme]!!.second)
|
||||||
},
|
},
|
||||||
colors = listItemColors,
|
colors = listItemColors,
|
||||||
modifier = modifier
|
items = items,
|
||||||
.fillMaxWidth()
|
index = index,
|
||||||
.clickable { showDialog = true }
|
modifier = modifier.fillMaxWidth()
|
||||||
)
|
) { showDialog = true }
|
||||||
}
|
}
|
||||||
16
app/src/main/res/drawable/colors.xml
Normal file
16
app/src/main/res/drawable/colors.xml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<!--
|
||||||
|
~ Copyright (c) 2025 Nishant Mishra
|
||||||
|
~
|
||||||
|
~ You should have received a copy of the GNU General Public License
|
||||||
|
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="960"
|
||||||
|
android:viewportHeight="960">
|
||||||
|
<path
|
||||||
|
android:fillColor="#e3e3e3"
|
||||||
|
android:pathData="M346,820 L100,574q-10,-10 -15,-22t-5,-25q0,-13 5,-25t15,-22l230,-229 -75,-75q-13,-13 -13.5,-31t12.5,-32q13,-14 32,-14t33,14l367,367q10,10 14.5,22t4.5,25q0,13 -4.5,25T686,574L440,820q-10,10 -22,15t-25,5q-13,0 -25,-5t-22,-15ZM393,314L179,528h428L393,314ZM792,840q-36,0 -61,-25.5T706,752q0,-27 13.5,-51t30.5,-47l19,-24q9,-11 23.5,-11.5T816,629l20,25q16,23 30,47t14,51q0,37 -26,62.5T792,840Z" />
|
||||||
|
</vector>
|
||||||
Reference in New Issue
Block a user