Рефактор файла с компонентами
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
package ru.megboyzz.dnevnik
|
||||
|
||||
import androidx.compose.animation.ExperimentalAnimationApi
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.Card
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.rememberScaffoldState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.google.accompanist.navigation.animation.rememberAnimatedNavController
|
||||
import ru.megboyzz.dnevnik.screens.ui.*
|
||||
import ru.megboyzz.dnevnik.ui.theme.mainBlue
|
||||
import ru.megboyzz.dnevnik.ui.theme.white
|
||||
|
||||
//Файл со всеми превьюшками
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun text() {
|
||||
Row(Modifier.fillMaxWidth()) {
|
||||
AlmostOutlinedText(text = "Здарова карова")
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalAnimationApi::class)
|
||||
@Preview
|
||||
@Composable
|
||||
fun DrawerPrev() {
|
||||
val scaffoldState = rememberScaffoldState()
|
||||
val navController = rememberAnimatedNavController()
|
||||
Box(Modifier.background(mainBlue)) {
|
||||
DrawerContent(navController = navController, scaffoldState = scaffoldState)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun CardWithAveragePrev() {
|
||||
CardWithAverage(
|
||||
averageMark = 4.33f,
|
||||
resultMark = 4f
|
||||
) {
|
||||
Box(Modifier.padding(10.dp)){
|
||||
Text("hehe")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun BaseCardPrev() {
|
||||
Box(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
){
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(10.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 20.dp)
|
||||
) {
|
||||
|
||||
Card(
|
||||
backgroundColor = white,
|
||||
shape = RoundedCornerShape(10.dp),
|
||||
border = BorderStroke(
|
||||
width = 1.dp,
|
||||
color = mainBlue
|
||||
),
|
||||
modifier = Modifier.defaultMinSize(minWidth = 300.dp)
|
||||
) {
|
||||
Box(
|
||||
Modifier
|
||||
.size(50.dp)
|
||||
.background(Color.Red)){}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun MonthTglPrev() {
|
||||
MonthToggle(
|
||||
startMonth = Month.January, startYear = 2023
|
||||
){
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun UnderlinedTextPrev() {
|
||||
Box(Modifier.background(white)){
|
||||
UnderlinedText(text = "Общая сводка")
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun CirclePrev() {
|
||||
val list = listOf(
|
||||
PieChartData(legend = "История", value=5),
|
||||
PieChartData(legend = "Русский язык", value=4),
|
||||
PieChartData(legend = "Химия", value=1),
|
||||
PieChartData(legend = "Математика", value=3)
|
||||
)
|
||||
PieChart(list)
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun GoodPieChartPrev() {
|
||||
val list = listOf(
|
||||
PieChartData(legend = "История", value=5),
|
||||
PieChartData(legend = "Русский язык", value=4),
|
||||
PieChartData(legend = "Химия", value=1),
|
||||
PieChartData(legend = "Математика", value=3),
|
||||
)
|
||||
PieChart(diagramData = list)
|
||||
}
|
||||
@@ -176,7 +176,8 @@ fun BottomNavButton(
|
||||
color: Color = white,
|
||||
onClick: () -> Unit,
|
||||
) {
|
||||
Box(Modifier.mainClickable(onClick = onClick, radius = 30.dp).padding(10.dp)) {
|
||||
//Возможно стоит убрать анимацию клика
|
||||
Box(Modifier.mainClickable(onClick = onClick, radius = 20.dp).padding(10.dp)) {
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center
|
||||
@@ -196,111 +197,6 @@ fun BottomNavButton(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@SuppressLint("CoroutineCreationDuringComposition")
|
||||
@Composable
|
||||
fun DrawerContent(
|
||||
navController: NavController,
|
||||
scaffoldState: ScaffoldState
|
||||
) {
|
||||
|
||||
// УЖАСНЫЙ КОСТЫЛЬ ДЛЯ ПЕРЕХОДОВ С ПОМОЩЬЮ СТЕЙТОВ TODO - УБРАТЬ
|
||||
val goToMarks = remember { mutableStateOf(false) }
|
||||
val goToHw = remember { mutableStateOf(false) }
|
||||
val goToSchedule = remember { mutableStateOf(false) }
|
||||
|
||||
val scope = rememberCoroutineScope()
|
||||
if(goToMarks.value){
|
||||
navController.navigate(AppNavRoute.Marks)
|
||||
scope.launch { scaffoldState.drawerState.close() }
|
||||
}
|
||||
if(goToHw.value){
|
||||
navController.navigate(AppNavRoute.HomeWorks)
|
||||
scope.launch { scaffoldState.drawerState.close() }
|
||||
}
|
||||
if(goToSchedule.value){
|
||||
navController.navigate(AppNavRoute.Schedule)
|
||||
scope.launch { scaffoldState.drawerState.close() }
|
||||
}
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.width(260.dp)
|
||||
.fillMaxSize()
|
||||
.padding(10.dp),
|
||||
horizontalAlignment = Alignment.Start
|
||||
){
|
||||
SpacerHeight(10.dp)
|
||||
ProfileCard(painter = R.drawable.ic_author.AsPainter())
|
||||
SpacerHeight(15.dp)
|
||||
AlmostOutlinedText(text = "Идет 3-я четверть")
|
||||
SpacerHeight(20.dp)
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(5.dp),
|
||||
modifier = Modifier.padding(5.dp, 0.dp)
|
||||
) {
|
||||
DrawerMainButton(
|
||||
icon = R.drawable.ic_marks.AsPainter(),
|
||||
text = R.string.title_marks.AsString()
|
||||
) { goToMarks.value = true }
|
||||
DrawerMainButton(
|
||||
icon = R.drawable.ic_homework.AsPainter(),
|
||||
text = R.string.title_hw.AsString()
|
||||
) { goToHw.value = true }
|
||||
DrawerMainButton(
|
||||
icon = R.drawable.ic_schedule.AsPainter(),
|
||||
text = R.string.title_schedule.AsString()
|
||||
) { goToSchedule.value = true }
|
||||
DrawerMainButton(
|
||||
icon = R.drawable.ic_settings.AsPainter(),
|
||||
text = R.string.title_settings.AsString()
|
||||
) { /* TODO */ }
|
||||
}
|
||||
Spacer(Modifier.weight(1f))
|
||||
Divider(color = white, thickness = 1.dp)
|
||||
SpacerHeight(5.dp)
|
||||
Column(Modifier.padding(5.dp, 0.dp)) {
|
||||
DrawerMainButton(
|
||||
icon = R.drawable.ic_exit.AsPainter(),
|
||||
text = R.string.title_leave_from_acconut.AsString()
|
||||
) { /* TODO */ }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val drawerShape = object : Shape {
|
||||
override fun createOutline(
|
||||
size: Size,
|
||||
layoutDirection: LayoutDirection,
|
||||
density: Density
|
||||
): Outline.Rounded {
|
||||
|
||||
val radius = CornerRadius(30f, 30f)
|
||||
val nullRadius = CornerRadius.Zero
|
||||
|
||||
return Outline.Rounded(RoundRect(
|
||||
left = 0f,
|
||||
top = 0f,
|
||||
right = size.width * 26 / 36,
|
||||
bottom = size.height,
|
||||
topLeftCornerRadius = nullRadius,
|
||||
topRightCornerRadius = radius,
|
||||
bottomRightCornerRadius = radius,
|
||||
bottomLeftCornerRadius = nullRadius
|
||||
))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun text() {
|
||||
Row(Modifier.fillMaxWidth()) {
|
||||
AlmostOutlinedText(text = "Здарова карова")
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun AlmostOutlinedText(
|
||||
text: String
|
||||
@@ -398,17 +294,19 @@ fun MainTextField(
|
||||
OutlinedTextField(
|
||||
value = value.value,
|
||||
onValueChange = onChange,
|
||||
label = { Text(
|
||||
label = {
|
||||
Text(
|
||||
text = label,
|
||||
style = H2,
|
||||
color = dark
|
||||
) },
|
||||
)
|
||||
},
|
||||
shape = RoundedCornerShape(10.dp),
|
||||
textStyle = H2,
|
||||
colors = TextFieldDefaults.outlinedTextFieldColors(
|
||||
textColor = dark,
|
||||
unfocusedBorderColor = if(isError.value) falseColor else mainBlue,
|
||||
focusedBorderColor = if(isError.value) falseColor else mainBlue,
|
||||
unfocusedBorderColor = if (isError.value) falseColor else mainBlue,
|
||||
focusedBorderColor = if (isError.value) falseColor else mainBlue,
|
||||
focusedLabelColor = dark,
|
||||
unfocusedLabelColor = dark,
|
||||
cursorColor = dark
|
||||
@@ -418,19 +316,19 @@ fun MainTextField(
|
||||
keyboardType = keyboardType
|
||||
),
|
||||
visualTransformation =
|
||||
if(keyboardType == KeyboardType.Password) {
|
||||
if (keyboardType == KeyboardType.Password) {
|
||||
if (passwordVisible)
|
||||
VisualTransformation.None
|
||||
else
|
||||
PasswordVisualTransformation()
|
||||
}else VisualTransformation.None,
|
||||
} else VisualTransformation.None,
|
||||
trailingIcon = {
|
||||
if(keyboardType == KeyboardType.Password){
|
||||
if (keyboardType == KeyboardType.Password) {
|
||||
val image = if (passwordVisible)
|
||||
Icons.Filled.Visibility
|
||||
else Icons.Filled.VisibilityOff
|
||||
|
||||
IconButton(onClick = {passwordVisible = !passwordVisible}){
|
||||
IconButton(onClick = { passwordVisible = !passwordVisible }) {
|
||||
Icon(imageVector = image, "")
|
||||
}
|
||||
}
|
||||
@@ -445,51 +343,6 @@ fun MainTextField(
|
||||
)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalAnimationApi::class)
|
||||
@Preview
|
||||
@Composable
|
||||
fun DrawerPrev() {
|
||||
val scaffoldState = rememberScaffoldState()
|
||||
val navController = rememberAnimatedNavController()
|
||||
Box(Modifier.background(mainBlue)) {
|
||||
DrawerContent(navController = navController, scaffoldState = scaffoldState)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun DrawerMainButton(
|
||||
icon: Painter,
|
||||
text: String,
|
||||
textColor: Color = white,
|
||||
onClick: () -> Unit = {}
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(30.dp)
|
||||
//TODO Сделать нормальную анимаую клика(не квадратную)
|
||||
.mainClickable(onClick = onClick),
|
||||
verticalArrangement = Arrangement.Center
|
||||
) {
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.Start
|
||||
){
|
||||
Image(
|
||||
painter = icon,
|
||||
contentDescription = "icon"
|
||||
)
|
||||
SpacerWidth(13.dp)
|
||||
Text(
|
||||
text = text,
|
||||
style = H2,
|
||||
color = textColor
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Composable
|
||||
fun MainCheckbox(
|
||||
isChecked: MutableState<Boolean>,
|
||||
@@ -840,55 +693,6 @@ fun CardWithAverage(
|
||||
) { content() }
|
||||
}
|
||||
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun CardWithAveragePrev() {
|
||||
CardWithAverage(
|
||||
averageMark = 4.33f,
|
||||
resultMark = 4f
|
||||
) {
|
||||
Box(Modifier.padding(10.dp)){
|
||||
Text("hehe")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun BaseCardPrev() {
|
||||
Box(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
){
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(10.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 20.dp)
|
||||
) {
|
||||
|
||||
Card(
|
||||
backgroundColor = white,
|
||||
shape = RoundedCornerShape(10.dp),
|
||||
border = BorderStroke(
|
||||
width = 1.dp,
|
||||
color = mainBlue
|
||||
),
|
||||
modifier = Modifier.defaultMinSize(minWidth = 300.dp)
|
||||
) {
|
||||
Box(
|
||||
Modifier
|
||||
.size(50.dp)
|
||||
.background(Color.Red)){}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Composable
|
||||
fun LastMarkCard(
|
||||
subjectName: String,
|
||||
@@ -962,20 +766,6 @@ enum class Month{
|
||||
December,
|
||||
}
|
||||
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun CardCalendarPrev() {
|
||||
Column() {
|
||||
CardCalendar(month = Month.March, year = 2023){
|
||||
|
||||
}
|
||||
Button(onClick = { /*TODO*/ }) {
|
||||
Text("hello")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun CardCalendar(
|
||||
month: Month,
|
||||
@@ -1221,16 +1011,6 @@ fun MonthToggle(
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun MonthTglPrev() {
|
||||
MonthToggle(
|
||||
startMonth = Month.January, startYear = 2023
|
||||
){
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun UnderlinedText(
|
||||
text: String
|
||||
@@ -1256,15 +1036,6 @@ fun UnderlinedText(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun UnderlinedTextPrev() {
|
||||
Box(Modifier.background(white)){
|
||||
UnderlinedText(text = "Общая сводка")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Класс для предоставления данных для круговых диаграм
|
||||
* Идея предоставить диаграмме массив именованных данных
|
||||
@@ -1287,32 +1058,6 @@ data class PieChartData(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun CirclePrev() {
|
||||
val list = listOf(
|
||||
PieChartData(legend = "История", value=5),
|
||||
PieChartData(legend = "Русский язык", value=4),
|
||||
PieChartData(legend = "Химия", value=1),
|
||||
PieChartData(legend = "Математика", value=3)
|
||||
)
|
||||
PieChart(list)
|
||||
}
|
||||
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun GoodPieChartPrev() {
|
||||
val list = listOf(
|
||||
PieChartData(legend = "История", value=5),
|
||||
PieChartData(legend = "Русский язык", value=4),
|
||||
PieChartData(legend = "Химия", value=1),
|
||||
PieChartData(legend = "Математика", value=3),
|
||||
)
|
||||
PieChart(diagramData = list)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun PieChart(
|
||||
diagramData: List<PieChartData>
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
package ru.megboyzz.dnevnik.screens.ui
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.Divider
|
||||
import androidx.compose.material.ScaffoldState
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.geometry.CornerRadius
|
||||
import androidx.compose.ui.geometry.RoundRect
|
||||
import androidx.compose.ui.geometry.Size
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.Outline
|
||||
import androidx.compose.ui.graphics.Shape
|
||||
import androidx.compose.ui.graphics.painter.Painter
|
||||
import androidx.compose.ui.unit.Density
|
||||
import androidx.compose.ui.unit.LayoutDirection
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.navigation.NavController
|
||||
import kotlinx.coroutines.launch
|
||||
import ru.megboyzz.dnevnik.*
|
||||
import ru.megboyzz.dnevnik.R
|
||||
import ru.megboyzz.dnevnik.navigation.AppNavRoute
|
||||
import ru.megboyzz.dnevnik.ui.theme.H2
|
||||
import ru.megboyzz.dnevnik.ui.theme.white
|
||||
|
||||
@SuppressLint("CoroutineCreationDuringComposition")
|
||||
@Composable
|
||||
fun DrawerContent(
|
||||
navController: NavController,
|
||||
scaffoldState: ScaffoldState
|
||||
) {
|
||||
|
||||
// УЖАСНЫЙ КОСТЫЛЬ ДЛЯ ПЕРЕХОДОВ С ПОМОЩЬЮ СТЕЙТОВ TODO - УБРАТЬ
|
||||
val goToMarks = remember { mutableStateOf(false) }
|
||||
val goToHw = remember { mutableStateOf(false) }
|
||||
val goToSchedule = remember { mutableStateOf(false) }
|
||||
|
||||
val scope = rememberCoroutineScope()
|
||||
if(goToMarks.value){
|
||||
navController.navigate(AppNavRoute.Marks)
|
||||
scope.launch { scaffoldState.drawerState.close() }
|
||||
}
|
||||
if(goToHw.value){
|
||||
navController.navigate(AppNavRoute.HomeWorks)
|
||||
scope.launch { scaffoldState.drawerState.close() }
|
||||
}
|
||||
if(goToSchedule.value){
|
||||
navController.navigate(AppNavRoute.Schedule)
|
||||
scope.launch { scaffoldState.drawerState.close() }
|
||||
}
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.width(260.dp)
|
||||
.fillMaxSize()
|
||||
.padding(10.dp),
|
||||
horizontalAlignment = Alignment.Start
|
||||
){
|
||||
SpacerHeight(10.dp)
|
||||
ProfileCard(painter = R.drawable.ic_author.AsPainter())
|
||||
SpacerHeight(15.dp)
|
||||
AlmostOutlinedText(text = "Идет 3-я четверть")
|
||||
SpacerHeight(20.dp)
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(5.dp),
|
||||
modifier = Modifier.padding(5.dp, 0.dp)
|
||||
) {
|
||||
DrawerMainButton(
|
||||
icon = R.drawable.ic_marks.AsPainter(),
|
||||
text = R.string.title_marks.AsString()
|
||||
) { goToMarks.value = true }
|
||||
DrawerMainButton(
|
||||
icon = R.drawable.ic_homework.AsPainter(),
|
||||
text = R.string.title_hw.AsString()
|
||||
) { goToHw.value = true }
|
||||
DrawerMainButton(
|
||||
icon = R.drawable.ic_schedule.AsPainter(),
|
||||
text = R.string.title_schedule.AsString()
|
||||
) { goToSchedule.value = true }
|
||||
DrawerMainButton(
|
||||
icon = R.drawable.ic_settings.AsPainter(),
|
||||
text = R.string.title_settings.AsString()
|
||||
) { /* TODO */ }
|
||||
}
|
||||
Spacer(Modifier.weight(1f))
|
||||
Divider(color = white, thickness = 1.dp)
|
||||
SpacerHeight(5.dp)
|
||||
Column(Modifier.padding(5.dp, 0.dp)) {
|
||||
DrawerMainButton(
|
||||
icon = R.drawable.ic_exit.AsPainter(),
|
||||
text = R.string.title_leave_from_acconut.AsString()
|
||||
) { /* TODO */ }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val drawerShape = object : Shape {
|
||||
override fun createOutline(
|
||||
size: Size,
|
||||
layoutDirection: LayoutDirection,
|
||||
density: Density
|
||||
): Outline.Rounded {
|
||||
|
||||
val radius = CornerRadius(30f, 30f)
|
||||
val nullRadius = CornerRadius.Zero
|
||||
|
||||
return Outline.Rounded(
|
||||
RoundRect(
|
||||
left = 0f,
|
||||
top = 0f,
|
||||
right = size.width * 26 / 36,
|
||||
bottom = size.height,
|
||||
topLeftCornerRadius = nullRadius,
|
||||
topRightCornerRadius = radius,
|
||||
bottomRightCornerRadius = radius,
|
||||
bottomLeftCornerRadius = nullRadius
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun DrawerMainButton(
|
||||
icon: Painter,
|
||||
text: String,
|
||||
textColor: Color = white,
|
||||
onClick: () -> Unit = {}
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(30.dp)
|
||||
.mainClickable(onClick = onClick),
|
||||
verticalArrangement = Arrangement.Center
|
||||
) {
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.Start
|
||||
){
|
||||
Image(
|
||||
painter = icon,
|
||||
contentDescription = "icon"
|
||||
)
|
||||
SpacerWidth(13.dp)
|
||||
Text(
|
||||
text = text,
|
||||
style = H2,
|
||||
color = textColor
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,168 +0,0 @@
|
||||
package ru.megboyzz.dnevnik.screens.ui
|
||||
|
||||
import androidx.compose.animation.core.Animatable
|
||||
import androidx.compose.animation.core.Spring
|
||||
import androidx.compose.animation.core.spring
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.clickable
|
||||
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.Icon
|
||||
import androidx.compose.material.IconButton
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.CheckCircle
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.draw.scale
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.Shape
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.TextUnit
|
||||
import androidx.compose.ui.unit.dp
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Composable
|
||||
fun SelectableItem(
|
||||
modifier: Modifier = Modifier,
|
||||
selected: Boolean,
|
||||
title: String,
|
||||
titleColor: Color =
|
||||
if (selected) MaterialTheme.colors.primary
|
||||
else MaterialTheme.colors.onSurface.copy(alpha = 0.2f),
|
||||
titleSize: TextUnit = MaterialTheme.typography.h6.fontSize,
|
||||
titleWeight: FontWeight = FontWeight.Medium,
|
||||
subtitle: String? = null,
|
||||
subtitleColor: Color =
|
||||
if (selected) MaterialTheme.colors.onSurface
|
||||
else MaterialTheme.colors.onSurface.copy(alpha = 0.2f),
|
||||
borderWidth: Dp = 1.dp,
|
||||
borderColor: Color =
|
||||
if (selected) MaterialTheme.colors.primary
|
||||
else MaterialTheme.colors.onSurface.copy(alpha = 0.2f),
|
||||
borderShape: Shape = RoundedCornerShape(size = 10.dp),
|
||||
icon: ImageVector = Icons.Default.CheckCircle,
|
||||
iconColor: Color =
|
||||
if (selected) MaterialTheme.colors.primary
|
||||
else MaterialTheme.colors.onSurface.copy(alpha = 0.2f),
|
||||
onClick: () -> Unit
|
||||
) {
|
||||
val scaleA = remember { Animatable(initialValue = 1f) }
|
||||
val scaleB = remember { Animatable(initialValue = 1f) }
|
||||
|
||||
val clickEnabled = remember { mutableStateOf(true) }
|
||||
|
||||
LaunchedEffect(key1 = selected) {
|
||||
if (selected) {
|
||||
clickEnabled.value = false
|
||||
|
||||
val jobA = launch {
|
||||
scaleA.animateTo(
|
||||
targetValue = 0.3f,
|
||||
animationSpec = tween(
|
||||
durationMillis = 50
|
||||
)
|
||||
)
|
||||
scaleA.animateTo(
|
||||
targetValue = 1f,
|
||||
animationSpec = spring(
|
||||
dampingRatio = Spring.DampingRatioLowBouncy,
|
||||
stiffness = Spring.StiffnessLow
|
||||
)
|
||||
)
|
||||
}
|
||||
val jobB = launch {
|
||||
scaleB.animateTo(
|
||||
targetValue = 0.9f,
|
||||
animationSpec = tween(
|
||||
durationMillis = 50
|
||||
)
|
||||
)
|
||||
scaleB.animateTo(
|
||||
targetValue = 1f,
|
||||
animationSpec = spring(
|
||||
dampingRatio = Spring.DampingRatioLowBouncy,
|
||||
stiffness = Spring.StiffnessLow
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
jobA.join()
|
||||
jobB.join()
|
||||
clickEnabled.value = true
|
||||
}
|
||||
}
|
||||
|
||||
Column(
|
||||
modifier = modifier
|
||||
.scale(scale = scaleB.value)
|
||||
.border(
|
||||
width = borderWidth,
|
||||
color = borderColor,
|
||||
shape = borderShape
|
||||
)
|
||||
.clip(borderShape)
|
||||
.clickable(enabled = clickEnabled.value) {
|
||||
onClick()
|
||||
}
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.padding(start = 12.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.weight(8f),
|
||||
text = title,
|
||||
style = TextStyle(
|
||||
color = titleColor,
|
||||
fontSize = titleSize,
|
||||
fontWeight = titleWeight
|
||||
),
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
IconButton(
|
||||
modifier = Modifier
|
||||
.weight(2f)
|
||||
.scale(scale = scaleA.value),
|
||||
onClick = {
|
||||
if (clickEnabled.value) {
|
||||
onClick()
|
||||
}
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
imageVector = icon,
|
||||
contentDescription = "Selectable Item Icon",
|
||||
tint = iconColor
|
||||
)
|
||||
}
|
||||
}
|
||||
if (subtitle != null) {
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 12.dp)
|
||||
.padding(bottom = 12.dp),
|
||||
text = subtitle,
|
||||
style = TextStyle(
|
||||
color = subtitleColor
|
||||
),
|
||||
maxLines = 3,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user