Skip to content

Commit

Permalink
Implemented school notices
Browse files Browse the repository at this point in the history
  • Loading branch information
aeoliux committed Oct 27, 2024
1 parent 288fc58 commit b1b7309
Show file tree
Hide file tree
Showing 12 changed files with 253 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.github.aeoliux.violet.api.bodys.Classrooms
import com.github.aeoliux.violet.api.bodys.Colors
import com.github.aeoliux.violet.api.bodys.LuckyNumbers
import com.github.aeoliux.violet.api.bodys.Me
import com.github.aeoliux.violet.api.bodys.SchoolNotices
import com.github.aeoliux.violet.api.bodys.Subjects
import com.github.aeoliux.violet.api.bodys.Timetables
import com.github.aeoliux.violet.api.bodys.Users
Expand All @@ -20,6 +21,7 @@ import com.github.aeoliux.violet.api.types.AttendanceItem
import com.github.aeoliux.violet.api.types.ClassInfo
import com.github.aeoliux.violet.api.types.Grade
import com.github.aeoliux.violet.api.types.Lesson
import com.github.aeoliux.violet.api.types.SchoolNotice
import com.github.aeoliux.violet.api.types.User
import io.ktor.client.HttpClient
import io.ktor.client.call.body
Expand Down Expand Up @@ -99,7 +101,6 @@ class ApiClient {
suspend fun timetable(): Timetable {
val today = Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault()).date
val weekDay = today.dayOfWeek.isoDayNumber
println(weekDay)
val weekStarts = if (weekDay > 5) {
LocalDate.fromEpochDays(today.toEpochDays() + 8 - weekDay)
} else {
Expand All @@ -126,6 +127,10 @@ class ApiClient {
subjects
)
}

suspend fun schoolNotices(): List<SchoolNotice> {
return data<SchoolNotices>("SchoolNotices").toSNList(users)
}
}

typealias Timetable = LinkedHashMap<LocalDate, LinkedHashMap<LocalTime, List<Lesson>>>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.github.aeoliux.violet.api.bodys

import com.github.aeoliux.violet.api.localDateTimeFormat
import com.github.aeoliux.violet.api.types.User
import kotlinx.datetime.LocalDate
import kotlinx.datetime.LocalDateTime
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toInstant
import kotlinx.serialization.Serializable

@Serializable
data class SchoolNotice(
val Id: String,
val StartDate: String,
val EndDate: String,
val Subject: String,
val Content: String,
val AddedBy: IdAndUrl,
val CreationDate: String,
val WasRead: Boolean
)

@Serializable
data class SchoolNotices(val SchoolNotices: List<SchoolNotice>) {
fun toSNList(
users: LinkedHashMap<UInt, User>
): List<com.github.aeoliux.violet.api.types.SchoolNotice> {
return SchoolNotices.fold<SchoolNotice, List<com.github.aeoliux.violet.api.types.SchoolNotice>>(emptyList()) { acc, cur ->
acc.plus(
com.github.aeoliux.violet.api.types.SchoolNotice(
startDate = LocalDate.parse(cur.StartDate),
endDate = LocalDate.parse(cur.EndDate),
subject = cur.Subject,
content = cur.Content,
addedBy = users[cur.AddedBy.Id]?.teacher()?: "",
createdAt = LocalDateTime.parse(cur.CreationDate, localDateTimeFormat)
)
)
}.sortedWith { a, b ->
(b.createdAt.toInstant(TimeZone.currentSystemDefault()).epochSeconds - a.createdAt.toInstant(
TimeZone.currentSystemDefault()
).epochSeconds).toInt()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,13 @@ data class AgendaItem(
val classroom: String?,
val timeFrom: String,
val timeTo: String,
)

data class SchoolNotice(
val startDate: LocalDate,
val endDate: LocalDate,
val subject: String,
val content: String,
val addedBy: String,
val createdAt: LocalDateTime
)
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.github.aeoliux.violet.app.storage.insertAgenda
import com.github.aeoliux.violet.app.storage.insertAttendances
import com.github.aeoliux.violet.app.storage.insertGrades
import com.github.aeoliux.violet.app.storage.insertLessons
import com.github.aeoliux.violet.app.storage.insertSchoolNotices
import com.github.aeoliux.violet.app.storage.selectClassInfo
import com.github.aeoliux.violet.app.storage.setAboutMe
import com.github.aeoliux.violet.app.storage.setClassInfo
Expand Down Expand Up @@ -61,6 +62,12 @@ suspend fun AppState.fetchData(login: String? = null, password: String? = null)
)
}

setFetchStatus("Does your school do anything?") {
Database.insertSchoolNotices(
client.value.schoolNotices()
)
}

statusMessage.value = "Saving some data and refreshing the view..."
semester.value = classInfo.semester
databaseUpdated.value = !databaseUpdated.value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ fun AttendanceListView(
Card(Modifier.fillMaxWidth().wrapContentHeight().padding(10.dp)) {
ExpandableList(
header = {
Text(date.toString())
Text(
modifier = Modifier.padding(15.dp),
text = date.toString()
)
}
) {
attendances.forEach { (lessonNo, attendanceInfo) ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.material.Divider
import androidx.compose.material.Icon
import androidx.compose.material.icons.Icons
Expand Down Expand Up @@ -41,9 +42,9 @@ fun ExpandableList(
if (onChange != null)
onChange()
}
.height(50.dp)
.padding(start = 15.dp),
.wrapContentHeight(),
horizontalArrangement = Arrangement.Start,
verticalAlignment = Alignment.CenterVertically
) {
Column(Modifier.fillMaxHeight(),
verticalArrangement = Arrangement.Center,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ fun GradesView(vm: GradesViewModel = viewModel { GradesViewModel() }) {
return@forEach

Card {
ExpandableList({ Text(subject) }) {
ExpandableList({
Text(modifier = Modifier.padding(15.dp), text = subject)
}) {
GradeSemesterView(1u, grades)
GradeSemesterView(2u, grades)
}
Expand All @@ -53,7 +55,12 @@ fun GradesView(vm: GradesViewModel = viewModel { GradesViewModel() }) {
internal fun GradeSemesterView(semester: UInt, grades: List<Grade>) {
val appState = LocalAppState.current

ExpandableList({ Text("Semester $semester") }, expanded = appState.semester.value == semester) {
ExpandableList(
header = {
Text(modifier = Modifier.padding(15.dp), text ="Semester $semester")
},
expanded = appState.semester.value == semester
) {
grades.forEach { grade ->
if (grade.semester == semester) {
GradeComponent(grade)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import com.github.aeoliux.violet.app.appState.fetchData
import com.github.aeoliux.violet.app.attendance.AttendanceView
import com.github.aeoliux.violet.app.grades.GradesView
import com.github.aeoliux.violet.app.home.HomeView
import com.github.aeoliux.violet.app.schoolNotices.SchoolNoticesView
import com.github.aeoliux.violet.app.timetable.TimetableView
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
Expand All @@ -25,7 +26,8 @@ class MainViewModel(
TabItem("Grades") { GradesView() },
TabItem("Timetable") { TimetableView() },
TabItem("Attendance") { AttendanceView() },
TabItem("Agenda and homeworks") { AgendaView() }
TabItem("Agenda and homeworks") { AgendaView() },
TabItem("School notices") { SchoolNoticesView() }
)

private var _isRefreshing = MutableStateFlow(false)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package com.github.aeoliux.violet.app.schoolNotices

import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.material.Card
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.github.aeoliux.violet.app.appState.LocalAppState
import com.github.aeoliux.violet.app.components.ExpandableList
import com.github.aeoliux.violet.app.storage.Database
import com.github.aeoliux.violet.app.storage.selectSchoolNotice

@Composable
fun SchoolNoticesView(vm: SchoolNoticesViewModel = viewModel { SchoolNoticesViewModel() }) {
val appState = LocalAppState.current
val listOfSchoolNotices by vm.listOfSchoolNotices.collectAsState()

LaunchedEffect(appState.databaseUpdated) {
vm.launchedEffect()
}

listOfSchoolNotices.forEach {
Card(
Modifier
.fillMaxWidth()
.wrapContentHeight()
.padding(2.dp)
) {
ExpandableList(
header = {
Column(Modifier.padding(10.dp)) {
Text(
fontWeight = FontWeight.Bold,
fontSize = 20.sp,
text = it.subject
)
Text(
fontSize = 15.sp,
text = "Added at ${it.createdAt} by ${it.addedBy}"
)
}
}
) {
val schoolNotice = Database.selectSchoolNotice(it.id)!!

Column(Modifier.padding(10.dp)) {
Text("Starts at: ${schoolNotice.startDate}")
Text("Ends at: ${schoolNotice.endDate}\n\n")

Text(
modifier = Modifier.fillMaxWidth(),
textAlign = TextAlign.Justify,
text = schoolNotice.content
)
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.github.aeoliux.violet.app.schoolNotices

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.github.aeoliux.violet.api.types.SchoolNotice
import com.github.aeoliux.violet.app.storage.Database
import com.github.aeoliux.violet.app.storage.selectListOfSchoolNotices
import com.github.aeoliux.violet.app.storage.selectSchoolNotice
import comgithubaeoliuxvioletstorage.SelectListOfSchoolNotices
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch

class SchoolNoticesViewModel: ViewModel() {
private var _listOfSchoolNotices: MutableStateFlow<List<SelectListOfSchoolNotices>> = MutableStateFlow(emptyList())
val listOfSchoolNotices get() = _listOfSchoolNotices.asStateFlow()

fun launchedEffect() {
viewModelScope.launch {
_listOfSchoolNotices.update { Database.selectListOfSchoolNotices()?: emptyList() }
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.github.aeoliux.violet.app.storage

import com.github.aeoliux.violet.api.types.SchoolNotice
import comgithubaeoliuxvioletstorage.SelectListOfSchoolNotices
import kotlinx.datetime.LocalDate
import kotlinx.datetime.LocalDateTime


fun Database.selectListOfSchoolNotices(): List<SelectListOfSchoolNotices>? {
try {
val result = dbQuery.selectListOfSchoolNotices().executeAsList()
return result
} catch (_: NullPointerException) {
return null
}
}

fun Database.selectSchoolNotice(id: Long): SchoolNotice? {
val result = dbQuery.selectSchoolNotice(id).executeAsOneOrNull()

return if (result != null)
SchoolNotice(
startDate = LocalDate.parse(result.startDate),
endDate = LocalDate.parse(result.endDate),
subject = result.subject,
content = result.content,
addedBy = result.addedBy,
createdAt = LocalDateTime.parse(result.createdAt)
)
else
null
}

fun Database.insertSchoolNotices(sn: List<SchoolNotice>) {
dbQuery.transaction {
dbQuery.clearSchoolNotices()

sn.forEach { sn ->
dbQuery.insertSchoolNotices(
startDate = sn.startDate.toString(),
endDate = sn.endDate.toString(),
subject = sn.subject,
content = sn.content,
addedBy = sn.addedBy,
createdAt = sn.createdAt.toString()
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,26 @@ SELECT * FROM Agenda;

clearAgenda:
DELETE FROM Agenda;

CREATE TABLE SchoolNotices(
id INTEGER PRIMARY KEY NOT NULL,
startDate TEXT NOT NULL,
endDate TEXT NOT NULL,
subject TEXT NOT NULL,
content TEXT NOT NULL,
addedBy TEXT NOT NULL,
createdAt TEXT NOT NULL
);

insertSchoolNotices:
INSERT INTO SchoolNotices (startDate, endDate, subject, content, addedBy, createdAt)
VALUES (?, ?, ?, ?, ?, ?);

selectListOfSchoolNotices:
SELECT id, addedBy, subject, createdAt FROM SchoolNotices ORDER BY createdAt DESC;

selectSchoolNotice:
SELECT * FROM SchoolNotices WHERE id = ? LIMIT 1;

clearSchoolNotices:
DELETE FROM SchoolNotices;

0 comments on commit b1b7309

Please sign in to comment.