From 524bab9d6e5a09e5c7d0001b16f3ead54b27d134 Mon Sep 17 00:00:00 2001 From: sweetbread Date: Tue, 19 Mar 2024 20:06:38 +0300 Subject: [PATCH] Add extended ScheduleItem --- app/build.gradle.kts | 4 +- app/src/main/java/ru/sweetbread/unn/ui/API.kt | 13 +- .../ru/sweetbread/unn/ui/composes/Schedule.kt | 206 +++++++++++++++--- app/src/main/res/values-ru/strings.xml | 7 + app/src/main/res/values/strings.xml | 7 + 5 files changed, 205 insertions(+), 32 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index dc563e8..5715e27 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -51,6 +51,7 @@ dependencies { coreLibraryDesugaring(libs.desugar.jdk.libs) implementation(libs.androidx.core.ktx) + implementation(libs.androidx.core.splashscreen) implementation(libs.androidx.lifecycle.runtime.ktx) implementation(libs.androidx.activity.compose) implementation(platform(libs.androidx.compose.bom)) @@ -71,9 +72,6 @@ dependencies { androidTestImplementation(libs.androidx.ui.test.junit4) debugImplementation(libs.androidx.ui.tooling) debugImplementation(libs.androidx.ui.test.manifest) - implementation(libs.androidx.core.splashscreen) - - implementation(libs.androidx.navigation.compose) implementation(libs.ktor.client.core) diff --git a/app/src/main/java/ru/sweetbread/unn/ui/API.kt b/app/src/main/java/ru/sweetbread/unn/ui/API.kt index 2ba7ed0..bfa7835 100644 --- a/app/src/main/java/ru/sweetbread/unn/ui/API.kt +++ b/app/src/main/java/ru/sweetbread/unn/ui/API.kt @@ -7,6 +7,7 @@ import io.ktor.client.statement.bodyAsText import io.ktor.http.parameters import org.json.JSONArray import org.json.JSONObject +import ru.sweetbread.unn.R import ru.sweetbread.unn.ui.layout.LoginData import ru.sweetbread.unn.ui.layout.client import java.time.LocalDate @@ -26,9 +27,11 @@ enum class Type(val s: String) { Auditorium("auditorium") } -enum class LecturerRank(val s: String) { - Lecturer("Lecturer"), - SLecturer("Senior Lecturer") +enum class LecturerRank(val id: Int) { + Assistant(R.string.assistant), + Lecturer(R.string.lecturer), + SLecturer(R.string.slecturer), + AProfessor(R.string.aprofessor) } class ScheduleUnit(val oid: Int, @@ -119,7 +122,7 @@ private suspend fun getMyself(login: String) { ) } -suspend fun getSchedule(type: Type = Type.Student, id: String = ME.id, start: LocalDate, finish: LocalDate): ArrayList { +suspend fun getSchedule(type: Type = ME.type, id: String = ME.id, start: LocalDate, finish: LocalDate): ArrayList { val unnDatePattern = DateTimeFormatter.ofPattern("yyyy.MM.dd") val r = client.get("$ruzapiURL/schedule/${type.s}/$id") { @@ -144,7 +147,9 @@ suspend fun getSchedule(type: Type = Type.Student, id: String = ME.id, start: Lo oid = lecturer.getInt("lecturerOid"), uid = lecturer.getString("lecturerUID"), rank = when (lecturer.getString("lecturer_rank")) { + "АССИСТ" -> LecturerRank.Assistant "СТПРЕП" -> LecturerRank.SLecturer + "ДОЦЕНТ" -> LecturerRank.AProfessor else -> LecturerRank.Lecturer } ) 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 23a549a..ee28ef4 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 @@ -1,25 +1,33 @@ package ru.sweetbread.unn.ui.composes import android.util.Log +import androidx.compose.animation.AnimatedVisibility import androidx.compose.foundation.background import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.IntrinsicSize import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.aspectRatio +import androidx.compose.foundation.layout.fillMaxHeight 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 import androidx.compose.foundation.lazy.items import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.LinearProgressIndicator import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.material3.Text +import androidx.compose.material3.VerticalDivider import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope @@ -27,6 +35,7 @@ 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.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview @@ -36,6 +45,8 @@ import com.kizitonwose.calendar.compose.WeekCalendar import com.kizitonwose.calendar.compose.weekcalendar.rememberWeekCalendarState import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import org.intellij.lang.annotations.JdkConstants.HorizontalAlignment +import ru.sweetbread.unn.R import ru.sweetbread.unn.ui.Auditorium import ru.sweetbread.unn.ui.Building import ru.sweetbread.unn.ui.Discipline @@ -47,13 +58,14 @@ import ru.sweetbread.unn.ui.getSchedule import ru.sweetbread.unn.ui.theme.UNNTheme import java.time.DayOfWeek import java.time.LocalDate +import java.time.LocalDateTime import java.time.LocalTime import java.time.format.DateTimeFormatter @Composable fun Schedule() { val state = rememberWeekCalendarState( - firstDayOfWeek = DayOfWeek.MONDAY + firstDayOfWeek = DayOfWeek.MONDAY // TODO: set start and end weeks to September and July of current year ) Column { @@ -66,11 +78,10 @@ fun Schedule() { .padding(vertical = 16.dp) .aspectRatio(1f) // This is important for square sizing! .offset(2.dp) - .background(if (it.date == curDate) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.secondaryContainer) + .background(if (it.date == curDate) MaterialTheme.colorScheme.inversePrimary else MaterialTheme.colorScheme.surfaceContainer) .clickable( - onClick = { - curDate = it.date - } + onClick = { curDate = it.date }, + enabled = curDate != it.date ), contentAlignment = Alignment.Center, ) { @@ -90,12 +101,16 @@ fun ScheduleDay(modifier: Modifier = Modifier, date: LocalDate) { val scope = rememberCoroutineScope() var loadedDate by remember { mutableStateOf(LocalDate.MIN) } val lessons = remember { mutableListOf() } + var expanded by remember { mutableIntStateOf(0) } if (loadedDate == date) { Log.d("Loaded", "${date.format(DateTimeFormatter.ISO_DATE)} ${lessons.size}") LazyColumn (modifier) { - items(lessons) { - ScheduleItem(unit = it) + items(lessons) { // TODO: Add empty list notification + ScheduleItem(unit = it, modifier = Modifier.clickable { + expanded = if (it.oid == expanded) 0 + else it.oid + }, expanded = expanded == it.oid) } } } else { @@ -117,35 +132,128 @@ fun ScheduleDay(modifier: Modifier = Modifier, date: LocalDate) { } @Composable -fun ScheduleItem(modifier: Modifier = Modifier, unit: ScheduleUnit) { +fun ScheduleItem(modifier: Modifier = Modifier, unit: ScheduleUnit, expanded: Boolean = false) { + val begin = unit.begin.format(DateTimeFormatter.ofPattern("HH:mm")) + val end = unit.end.format(DateTimeFormatter.ofPattern("HH:mm")) + Row ( modifier .fillMaxWidth() .padding(4.dp) .clip(RoundedCornerShape(8.dp)) - .background(MaterialTheme.colorScheme.primaryContainer) + .background( + if ((LocalDateTime.of( + unit.date, + unit.begin + ) < LocalDateTime.now()) and (LocalDateTime.now() < LocalDateTime.of( + unit.date, + unit.end + )) + ) + MaterialTheme.colorScheme.primaryContainer + else MaterialTheme.colorScheme.secondaryContainer + ) .padding(8.dp) ){ Column (Modifier.weight(1f)) { - Text( - text = unit.discipline.name, - fontWeight = FontWeight.Bold, - modifier = Modifier.zIndex(1f), - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) - Text(text = unit.kindOfWork.name, maxLines = 1, overflow = TextOverflow.Ellipsis) - Row (Modifier) { - Text(text = unit.auditorium.name, fontWeight = FontWeight.Bold, modifier = Modifier.padding(end = 4.dp)) - Text(text = unit.auditorium.building.name, maxLines = 1, overflow = TextOverflow.Ellipsis) + Column { + Text( + text = unit.discipline.name, + fontWeight = FontWeight.Bold, + modifier = Modifier.zIndex(1f), + maxLines = if (expanded) Int.MAX_VALUE else 1, + overflow = TextOverflow.Ellipsis + ) + } + + AnimatedVisibility (expanded) { + HorizontalDivider( + modifier = Modifier.padding(vertical = 16.dp), + thickness = 1.dp, + color = MaterialTheme.colorScheme.onBackground + ) + } + + Column { + Text( + text = unit.kindOfWork.name, + overflow = TextOverflow.Ellipsis + ) + AnimatedVisibility (expanded) { + Text(text = unit.stream) + } + } + + AnimatedVisibility (expanded) { + HorizontalDivider( + modifier = Modifier.padding(vertical = 16.dp), + thickness = 1.dp, + color = MaterialTheme.colorScheme.onBackground + ) + } + + AnimatedVisibility (!expanded) { + Row(Modifier) { + Text( + text = unit.auditorium.name, + fontWeight = FontWeight.Bold, + modifier = Modifier.padding(end = 4.dp) + ) + Text( + text = unit.auditorium.building.name, + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + } + } + AnimatedVisibility (expanded) { + Column { + Text( + text = "${stringResource(R.string.auditorium)}: ${unit.auditorium.name}", + fontWeight = FontWeight.Bold, + modifier = Modifier.padding(end = 4.dp) + ) + Text( + text = "${stringResource(R.string.building)}: ${unit.auditorium.building.name}", + overflow = TextOverflow.Ellipsis + ) + if (unit.auditorium.floor != 0) { + Text( + text = "${stringResource(R.string.floor)}: ${unit.auditorium.floor}", + overflow = TextOverflow.Ellipsis + ) + } + + HorizontalDivider( + modifier = Modifier.padding(vertical = 16.dp), + thickness = 1.dp, + color = MaterialTheme.colorScheme.onBackground + ) + + Column { + Text(text = unit.lecturers[0].name, fontWeight = FontWeight.Bold) + Text(text = stringResource(unit.lecturers[0].rank.id)) + } + + HorizontalDivider( + modifier = Modifier.padding(vertical = 16.dp), + thickness = 1.dp, + color = MaterialTheme.colorScheme.onBackground + ) + + Row (Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) { + Text(begin.toString(), fontWeight = FontWeight.Bold) + Text(end.toString()) + } + } } } - Column { - val begin = unit.begin.format(DateTimeFormatter.ofPattern("HH:mm")) - val end = unit.end.format(DateTimeFormatter.ofPattern("HH:mm")) - Text(begin.toString(), fontWeight = FontWeight.Bold) - Text(end.toString()) + AnimatedVisibility (!expanded) { + Column { + Text(begin.toString(), fontWeight = FontWeight.Bold) + Text(end.toString()) + } } } } @@ -196,4 +304,52 @@ fun ScheduleItemPreview() { ScheduleItem(unit = unit) } } +} + +@Preview +@Composable +fun ScheduleExpandedItemPreview() { + val unit = ScheduleUnit( + oid = 1, + Auditorium( + name = "с/з 1(110)", + oid = 3752, + floor = 0, + building = Building( + name = "Корпус 6", + gid = 30, + oid = 155 + ), + ), + date = LocalDate.of(2024, 3, 11), + discipline = Discipline( + name = "Физическая культура и спорт (элективная дисциплина)", + oid = 67895, + type = 0 + ), + kindOfWork = KindOfWork( + name = "Практика (семинарские занятия)", + oid = 261, + uid = "281474976710661", + complexity = 1 + ), + lecturers = arrayListOf( + Lecturer( + name = "Фамилия Имя Отчество", + rank = LecturerRank.SLecturer, + email = "", + oid = 28000, + uid = "51000" + ) + ), + stream = "3823Б1ПР1|3823Б1ПР2|3823Б1ПР3|3823Б1ПР4|3823Б1ПР5-В-OUP", + begin = LocalTime.of(10, 50), + end = LocalTime.of(12, 20) + ) + + UNNTheme { + Surface(color = MaterialTheme.colorScheme.background) { + ScheduleItem(unit = unit, expanded = true) + } + } } \ No newline at end of file diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index d720e84..d95aa14 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -3,4 +3,11 @@ Пароль Логин Войти + Ассистент + Преподаватель + Старший Преподаватель + Доцент + Аудитория + Здание + Этаж \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 01d78ad..e1d98a0 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -5,5 +5,12 @@ Login Password Sign in + Assistant + Lecturer + Senior Lecturer + Assistant professor + Auditorium + Building + Floor \ No newline at end of file