Add extended ScheduleItem
This commit is contained in:
parent
983249091a
commit
524bab9d6e
@ -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)
|
||||
|
@ -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<ScheduleUnit> {
|
||||
suspend fun getSchedule(type: Type = ME.type, id: String = ME.id, start: LocalDate, finish: LocalDate): ArrayList<ScheduleUnit> {
|
||||
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
|
||||
}
|
||||
)
|
||||
|
@ -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<ScheduleUnit>() }
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
@ -3,4 +3,11 @@
|
||||
<string name="prompt_password">Пароль</string>
|
||||
<string name="prompt_login">Логин</string>
|
||||
<string name="sign_in">Войти</string>
|
||||
<string name="assistant">Ассистент</string>
|
||||
<string name="lecturer">Преподаватель</string>
|
||||
<string name="slecturer">Старший Преподаватель</string>
|
||||
<string name="aprofessor">Доцент</string>
|
||||
<string name="auditorium">Аудитория</string>
|
||||
<string name="building">Здание</string>
|
||||
<string name="floor">Этаж</string>
|
||||
</resources>
|
@ -5,5 +5,12 @@
|
||||
<string name="prompt_login">Login</string>
|
||||
<string name="prompt_password">Password</string>
|
||||
<string name="sign_in">Sign in</string>
|
||||
<string name="assistant">Assistant</string>
|
||||
<string name="lecturer">Lecturer</string>
|
||||
<string name="slecturer">Senior Lecturer</string>
|
||||
<string name="aprofessor">Assistant professor</string>
|
||||
<string name="auditorium">Auditorium</string>
|
||||
<string name="building">Building</string>
|
||||
<string name="floor">Floor</string>
|
||||
<!-- <string name="login_failed">"Login failed"</string>-->
|
||||
</resources>
|
Loading…
x
Reference in New Issue
Block a user