diff --git a/app/src/main/java/ru/sweetbread/unn/ui/composes/Schedule.kt b/app/src/main/java/ru/sweetbread/unn/ui/composes/Schedule.kt index 9446a07..1e82513 100644 --- a/app/src/main/java/ru/sweetbread/unn/ui/composes/Schedule.kt +++ b/app/src/main/java/ru/sweetbread/unn/ui/composes/Schedule.kt @@ -2,6 +2,7 @@ package ru.sweetbread.unn.ui.composes import android.util.Log import androidx.compose.animation.AnimatedVisibility +import androidx.compose.foundation.Canvas import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement @@ -10,6 +11,7 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn @@ -23,6 +25,7 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -31,15 +34,19 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.compose.ui.zIndex import com.kizitonwose.calendar.compose.WeekCalendar import com.kizitonwose.calendar.compose.weekcalendar.rememberWeekCalendarState import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.delay import kotlinx.coroutines.launch import ru.sweetbread.unn.Auditorium import ru.sweetbread.unn.Building @@ -56,7 +63,9 @@ import java.time.DayOfWeek import java.time.LocalDate import java.time.LocalDateTime import java.time.LocalTime +import java.time.ZoneId import java.time.format.DateTimeFormatter +import java.util.Calendar @Composable fun Schedule() { @@ -132,8 +141,30 @@ fun ScheduleDay(modifier: Modifier = Modifier, date: LocalDate) { @Composable fun ScheduleItem(modifier: Modifier = Modifier, unit: ScheduleUnit, expanded: Boolean = false) { + fun getRel(): Float { + val begin = LocalDateTime.of(unit.date, unit.begin).atZone(ZoneId.of("Europe/Moscow")).toEpochSecond() + val end = LocalDateTime.of(unit.date, unit.end).atZone(ZoneId.of("Europe/Moscow")).toEpochSecond() + val now = LocalDateTime.now().atZone(ZoneId.of("Europe/Moscow")).toEpochSecond() + if (begin > now) + return -1f + return (now - begin) / (end - begin).toFloat() + } + val begin = unit.begin.format(DateTimeFormatter.ofPattern("HH:mm")) val end = unit.end.format(DateTimeFormatter.ofPattern("HH:mm")) + var rel by remember { mutableFloatStateOf(getRel()) } + + LaunchedEffect(Unit) { + while (true) { + val now = System.currentTimeMillis() + val calendar = Calendar.getInstance().apply { timeInMillis = now } + val seconds = calendar.get(Calendar.SECOND) + val millisUntilNextMinute = (60 - seconds) * 1000L - calendar.get(Calendar.MILLISECOND) + + delay(millisUntilNextMinute) + rel = getRel() + } + } Row ( modifier @@ -141,16 +172,9 @@ fun ScheduleItem(modifier: Modifier = Modifier, unit: ScheduleUnit, expanded: Bo .padding(4.dp) .clip(RoundedCornerShape(8.dp)) .background( - if ((LocalDateTime.of( - unit.date, - unit.begin - ) < LocalDateTime.now()) and (LocalDateTime.now() < LocalDateTime.of( - unit.date, - unit.end - )) - ) + if (rel != -1f) MaterialTheme.colorScheme.primaryContainer - else MaterialTheme.colorScheme.secondaryContainer + else MaterialTheme.colorScheme.surfaceContainer ) .padding(8.dp) ){ @@ -240,8 +264,18 @@ fun ScheduleItem(modifier: Modifier = Modifier, unit: ScheduleUnit, expanded: Bo color = MaterialTheme.colorScheme.onBackground ) - Row (Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) { + Row (Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically) { Text(begin.toString(), fontWeight = FontWeight.Bold) + if (rel != -1f) + DividerWithMarker( + Modifier.weight(1f).padding(horizontal = 2.dp), + positionPercentage = rel, + color = MaterialTheme.colorScheme.outline, + thickness = 3.dp, + markerSize = 8.dp, + markerColor = MaterialTheme.colorScheme.primary) Text(end.toString()) } } @@ -257,6 +291,43 @@ fun ScheduleItem(modifier: Modifier = Modifier, unit: ScheduleUnit, expanded: Bo } } + +@Composable +fun DividerWithMarker( + modifier: Modifier = Modifier, + positionPercentage: Float, + color: Color = Color.Gray, + thickness: Dp = 1.dp, + markerSize: Dp = 8.dp, + markerColor: Color = Color.Red +) { + Canvas(modifier = modifier.height(thickness)) { + val dividerHeight = thickness.toPx() + val width = size.width + val markerX = width * positionPercentage + + drawLine( + color = markerColor, + start = Offset(0f, dividerHeight / 2), + end = Offset(markerX, dividerHeight / 2), + strokeWidth = dividerHeight + ) + + drawLine( + color = color, + start = Offset(markerX, dividerHeight / 2), + end = Offset(width, dividerHeight / 2), + strokeWidth = dividerHeight / 2 + ) + + drawCircle( + color = markerColor, + radius = markerSize.toPx() / 2, + center = Offset(markerX, dividerHeight / 2) + ) + } +} + @Preview @Composable fun ScheduleItemPreview() {