Skip to content

Commit

Permalink
Implemented agenda
Browse files Browse the repository at this point in the history
  • Loading branch information
aeoliux committed Oct 7, 2024
1 parent aa98086 commit 288fc58
Show file tree
Hide file tree
Showing 41 changed files with 589 additions and 126 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@ and from [here](https://nightly.link/aeoliux/Violet/workflows/build/main/release
## Things that are implemented
- Grades
- Lucky number
- Timetable
- Timetable
- Attendance
- Agenda
2 changes: 1 addition & 1 deletion composeApp/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ android {
sqldelight {
databases {
create("AppDatabase") {
packageName.set("com.github.aeoliux.violet.storage")
packageName.set("com.github.aeoliux.violet.app.storage")
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ actual class Keychain(private val context: Context) {

@OptIn(ExperimentalEncodingApi::class)
actual fun savePass(password: String) {
println(password)
val cipher = Cipher.getInstance("AES/GCM/NoPadding")
cipher.init(Cipher.ENCRYPT_MODE, key)
val iv = cipher.iv
Expand Down Expand Up @@ -71,6 +72,8 @@ actual class Keychain(private val context: Context) {
val gcmParameterSpec = GCMParameterSpec(128, iv)
cipher.init(Cipher.DECRYPT_MODE, key, gcmParameterSpec)

return String(cipher.doFinal(cipherText), Charsets.UTF_8)
val final = String(cipher.doFinal(cipherText), Charsets.UTF_8)
println(final)
return final
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import com.github.aeoliux.violet.storage.AppDatabase
import com.github.aeoliux.violet.storage.Database
import com.github.aeoliux.violet.storage.DatabaseDriverFactory
import com.github.aeoliux.violet.app.storage.AppDatabase
import com.github.aeoliux.violet.app.storage.Database
import com.github.aeoliux.violet.app.storage.DatabaseDriverFactory

class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.github.aeoliux.violet.storage
package com.github.aeoliux.violet.app.storage

import android.content.Context
import app.cash.sqldelight.ColumnAdapter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@ import com.github.aeoliux.violet.api.bodys.Me
import com.github.aeoliux.violet.api.bodys.Subjects
import com.github.aeoliux.violet.api.bodys.Timetables
import com.github.aeoliux.violet.api.bodys.Users
import com.github.aeoliux.violet.api.bodys.agenda.HomeworkCategories
import com.github.aeoliux.violet.api.bodys.agenda.Homeworks
import com.github.aeoliux.violet.api.bodys.attendance.Attendances
import com.github.aeoliux.violet.api.bodys.attendance.AttendancesTypes
import com.github.aeoliux.violet.api.bodys.grades.Grades
import com.github.aeoliux.violet.api.bodys.grades.GradesCategories
import com.github.aeoliux.violet.api.bodys.grades.GradesComments
import com.github.aeoliux.violet.api.types.AgendaItem
import com.github.aeoliux.violet.api.types.AttendanceItem
import com.github.aeoliux.violet.api.types.ClassInfo
import com.github.aeoliux.violet.api.types.Grade
Expand Down Expand Up @@ -113,7 +116,18 @@ class ApiClient {
users
)
}

suspend fun agenda(): Agenda {
return data<Homeworks>("HomeWorks")
.toAgenda(
data<HomeworkCategories>("HomeWorks/Categories").toMap(colors),
users,
classrooms,
subjects
)
}
}

typealias Timetable = LinkedHashMap<LocalDate, LinkedHashMap<LocalTime, List<Lesson>>>
typealias Attendance = LinkedHashMap<LocalDate, LinkedHashMap<UInt, AttendanceItem>>
typealias Attendance = LinkedHashMap<LocalDate, LinkedHashMap<UInt, AttendanceItem>>
typealias Agenda = LinkedHashMap<LocalDate, LinkedHashMap<UInt, List<AgendaItem>>>
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package com.github.aeoliux.violet.api

public object Endpoints {
public val authBase = "https://api.librus.pl/OAuth/Authorization"
public val authStep1 = authBase + "?client_id=46&response_type=code&scope=mydata"
public val authStep2 = authBase + "?client_id=46"
public val authStep3 = authBase + "/2FA?client_id=46"
object Endpoints {
val authBase = "https://api.librus.pl/OAuth/Authorization"
val authStep1 = authBase + "?client_id=46&response_type=code&scope=mydata"
val authStep2 = authBase + "?client_id=46"
val authStep3 = authBase + "/2FA?client_id=46"

public val apiEndpoint = "https://synergia.librus.pl/gateway/api/2.0/"
val apiEndpoint = "https://synergia.librus.pl/gateway/api/2.0/"

public fun url(data: String): String {
fun url(data: String): String {
return apiEndpoint + data
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.github.aeoliux.violet.api.bodys.agenda

import com.github.aeoliux.violet.api.Agenda
import com.github.aeoliux.violet.api.bodys.IdAndUrl
import com.github.aeoliux.violet.api.localDateTimeFormat
import com.github.aeoliux.violet.api.types.AgendaItem
import com.github.aeoliux.violet.api.types.User
import kotlinx.datetime.LocalDate
import kotlinx.datetime.LocalDateTime
import kotlinx.serialization.Serializable

@Serializable
data class HomeworkClassroom(
val Id: UInt,
val Symbol: String,
val Name: String,
val Size: UInt
)

@Serializable
data class Homework(
val Id: UInt,
val Content: String,
val Date: String,
val Category: IdAndUrl,
val LessonNo: UInt? = null,
val TimeFrom: String,
val TimeTo: String,
val CreatedBy: IdAndUrl,
val Classroom: HomeworkClassroom? = null,
val Subject: IdAndUrl? = null,
val AddDate: String
)

@Serializable
data class Homeworks(val HomeWorks: List<Homework>) {
fun toAgenda(
categories: LinkedHashMap<UInt, Pair<String, String>>,
users: LinkedHashMap<UInt, User>,
classrooms: LinkedHashMap<UInt, String>,
subjects: LinkedHashMap<UInt, String>
): Agenda {
return HomeWorks.fold(Agenda()) { acc, homework ->
val newHomework = AgendaItem(
content = homework.Content,
category = categories[homework.Category.Id]?.first?: "",
createdBy = users[homework.CreatedBy.Id]?.teacher()?: "",
addedAt = LocalDateTime.parse(homework.AddDate, localDateTimeFormat),
color = categories[homework.Category.Id]?.second?: "FFFFFF",
subject = subjects[homework.Subject?.Id?: 0],
classroom = classrooms[homework.Classroom?.Id?: 0],
timeFrom = homework.TimeFrom,
timeTo = homework.TimeTo
)

val date = LocalDate.parse(homework.Date)
if (acc[date] == null)
acc[date] = LinkedHashMap()

acc[date]!![homework.LessonNo?: 0u] =
acc[date]!![homework.LessonNo?: 0]?.plus(newHomework)?: listOf(newHomework)

acc
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.github.aeoliux.violet.api.bodys.agenda

import com.github.aeoliux.violet.api.bodys.IdAndUrl
import kotlinx.serialization.Serializable

@Serializable
data class HomeworkCategory(
val Id: UInt,
val Name: String,
val Color: IdAndUrl
)

@Serializable
data class HomeworkCategories(val Categories: List<HomeworkCategory>) {
fun toMap(colors: LinkedHashMap<UInt, String>): LinkedHashMap<UInt, Pair<String, String>> {
return Categories.fold(LinkedHashMap()) { acc, category ->
acc[category.Id] = Pair(category.Name, colors[category.Color.Id]?: "FFFFFF")
acc
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.github.aeoliux.violet.api.types

import kotlinx.datetime.LocalDate
import kotlinx.datetime.LocalDateTime

data class Me(
Expand Down Expand Up @@ -64,4 +65,16 @@ data class AttendanceItem(
val typeShort: String,
val type: String,
val color: String,
)

data class AgendaItem(
val content: String,
val category: String,
val createdBy: String,
val addedAt: LocalDateTime,
val color: String,
val subject: String?,
val classroom: String?,
val timeFrom: String,
val timeTo: String,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.github.aeoliux.violet.app.agenda

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.github.aeoliux.violet.api.types.AgendaItem
import com.github.aeoliux.violet.app.components.Dialog

@Composable
fun AgendaDialog(agendaItem: AgendaItem, onDismiss: () -> Unit) {
Dialog({ onDismiss() }) {
Column(Modifier.wrapContentSize()) {
Text("Category: ")
if (agendaItem.subject != null) Text("Subject: ")
if (agendaItem.classroom != null) Text("Classroom: ")
Text("Added by: ")
Text("Added at: ")
Text("Starts at: ")

Text("Content: ")
}
Column(Modifier.wrapContentHeight()) {
Text(agendaItem.category)
if (agendaItem.subject != null) Text(agendaItem.subject)
if (agendaItem.classroom != null) Text(agendaItem.classroom)
Text(agendaItem.createdBy)
Text(agendaItem.addedAt.toString())
Text(agendaItem.timeFrom)
Text(agendaItem.content)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package com.github.aeoliux.violet.app.agenda

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.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.shape.RoundedCornerShape
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.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.github.aeoliux.violet.api.toColorLong
import com.github.aeoliux.violet.app.appState.LocalAppState
import com.github.aeoliux.violet.app.components.Dialog
import kotlinx.datetime.Clock
import kotlinx.datetime.LocalDate
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toLocalDateTime

@Composable
fun AgendaView(vm: AgendaViewModel = viewModel { AgendaViewModel() }) {
val appState = LocalAppState.current
val isLoaded by vm.isLoaded.collectAsState()
val agenda by vm.agenda.collectAsState()
val isSomethingSelected by vm.isSomethingSelected.collectAsState()
val selectedAgendaItem by vm.selectedAgendaItem.collectAsState()

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

if (isLoaded) {
var dateIndex = Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault()).date.toEpochDays()
val startDate = dateIndex

while (dateIndex < startDate + 90) {
val date = LocalDate.fromEpochDays(dateIndex)

Card(
Modifier
.fillMaxWidth()
.wrapContentHeight()
.padding(2.dp)
) {
val agenda = agenda[date]

Column(
Modifier
.padding(10.dp)
.wrapContentHeight()
) {
Row {
Text(
text = "${date.dayOfMonth} ${date.month.name}",
fontWeight = FontWeight.Bold,
fontSize = 20.sp
)
}

agenda?.forEach { (lessonNo, agenda) ->
agenda.forEach { agendaItem ->
Row(Modifier
.padding(2.dp)
.border(width = 2.dp, color = agendaItem.color.toColorLong(), shape = RoundedCornerShape(10.dp))
.fillMaxWidth()) {
Column(Modifier.padding(10.dp).clickable { vm.showAgendaInfo(agendaItem) }) {
Text(
text = "${agendaItem.category} - ${agendaItem.content}",
fontWeight = FontWeight.SemiBold,
fontSize = 17.sp
)

Text("${agendaItem.timeFrom} ${
if (lessonNo != 0u)
" ($lessonNo)"
else
""
}, ${agendaItem.createdBy}, ${agendaItem.subject}")
}
}
}
}
}
}

dateIndex++
}

if (isSomethingSelected && selectedAgendaItem != null)
AgendaDialog(selectedAgendaItem!!) { vm.closeAgendaDialog() }
}
}
Loading

0 comments on commit 288fc58

Please sign in to comment.