refresh button working (not 100% test coverage)
This commit is contained in:
Generated
-340
@@ -1,340 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DeviceStreaming">
|
||||
<option name="deviceSelectionList">
|
||||
<list>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="27" />
|
||||
<option name="brand" value="DOCOMO" />
|
||||
<option name="codename" value="F01L" />
|
||||
<option name="id" value="F01L" />
|
||||
<option name="manufacturer" value="FUJITSU" />
|
||||
<option name="name" value="F-01L" />
|
||||
<option name="screenDensity" value="360" />
|
||||
<option name="screenX" value="720" />
|
||||
<option name="screenY" value="1280" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="OPPO" />
|
||||
<option name="codename" value="OP573DL1" />
|
||||
<option name="id" value="OP573DL1" />
|
||||
<option name="manufacturer" value="OPPO" />
|
||||
<option name="name" value="CPH2557" />
|
||||
<option name="screenDensity" value="480" />
|
||||
<option name="screenX" value="1080" />
|
||||
<option name="screenY" value="2400" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="28" />
|
||||
<option name="brand" value="DOCOMO" />
|
||||
<option name="codename" value="SH-01L" />
|
||||
<option name="id" value="SH-01L" />
|
||||
<option name="manufacturer" value="SHARP" />
|
||||
<option name="name" value="AQUOS sense2 SH-01L" />
|
||||
<option name="screenDensity" value="480" />
|
||||
<option name="screenX" value="1080" />
|
||||
<option name="screenY" value="2160" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="Lenovo" />
|
||||
<option name="codename" value="TB370FU" />
|
||||
<option name="id" value="TB370FU" />
|
||||
<option name="manufacturer" value="Lenovo" />
|
||||
<option name="name" value="Tab P12" />
|
||||
<option name="screenDensity" value="340" />
|
||||
<option name="screenX" value="1840" />
|
||||
<option name="screenY" value="2944" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="31" />
|
||||
<option name="brand" value="samsung" />
|
||||
<option name="codename" value="a51" />
|
||||
<option name="id" value="a51" />
|
||||
<option name="manufacturer" value="Samsung" />
|
||||
<option name="name" value="Galaxy A51" />
|
||||
<option name="screenDensity" value="420" />
|
||||
<option name="screenX" value="1080" />
|
||||
<option name="screenY" value="2400" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="google" />
|
||||
<option name="codename" value="akita" />
|
||||
<option name="id" value="akita" />
|
||||
<option name="manufacturer" value="Google" />
|
||||
<option name="name" value="Pixel 8a" />
|
||||
<option name="screenDensity" value="420" />
|
||||
<option name="screenX" value="1080" />
|
||||
<option name="screenY" value="2400" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="33" />
|
||||
<option name="brand" value="samsung" />
|
||||
<option name="codename" value="b0q" />
|
||||
<option name="id" value="b0q" />
|
||||
<option name="manufacturer" value="Samsung" />
|
||||
<option name="name" value="Galaxy S22 Ultra" />
|
||||
<option name="screenDensity" value="600" />
|
||||
<option name="screenX" value="1440" />
|
||||
<option name="screenY" value="3088" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="32" />
|
||||
<option name="brand" value="google" />
|
||||
<option name="codename" value="bluejay" />
|
||||
<option name="id" value="bluejay" />
|
||||
<option name="manufacturer" value="Google" />
|
||||
<option name="name" value="Pixel 6a" />
|
||||
<option name="screenDensity" value="420" />
|
||||
<option name="screenX" value="1080" />
|
||||
<option name="screenY" value="2400" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="google" />
|
||||
<option name="codename" value="caiman" />
|
||||
<option name="id" value="caiman" />
|
||||
<option name="manufacturer" value="Google" />
|
||||
<option name="name" value="Pixel 9 Pro" />
|
||||
<option name="screenDensity" value="360" />
|
||||
<option name="screenX" value="960" />
|
||||
<option name="screenY" value="2142" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="google" />
|
||||
<option name="codename" value="comet" />
|
||||
<option name="id" value="comet" />
|
||||
<option name="manufacturer" value="Google" />
|
||||
<option name="name" value="Pixel 9 Pro Fold" />
|
||||
<option name="screenDensity" value="390" />
|
||||
<option name="screenX" value="2076" />
|
||||
<option name="screenY" value="2152" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="29" />
|
||||
<option name="brand" value="samsung" />
|
||||
<option name="codename" value="crownqlteue" />
|
||||
<option name="id" value="crownqlteue" />
|
||||
<option name="manufacturer" value="Samsung" />
|
||||
<option name="name" value="Galaxy Note9" />
|
||||
<option name="screenDensity" value="420" />
|
||||
<option name="screenX" value="2220" />
|
||||
<option name="screenY" value="1080" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="samsung" />
|
||||
<option name="codename" value="dm3q" />
|
||||
<option name="id" value="dm3q" />
|
||||
<option name="manufacturer" value="Samsung" />
|
||||
<option name="name" value="Galaxy S23 Ultra" />
|
||||
<option name="screenDensity" value="600" />
|
||||
<option name="screenX" value="1440" />
|
||||
<option name="screenY" value="3088" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="samsung" />
|
||||
<option name="codename" value="e1q" />
|
||||
<option name="id" value="e1q" />
|
||||
<option name="manufacturer" value="Samsung" />
|
||||
<option name="name" value="Galaxy S24" />
|
||||
<option name="screenDensity" value="480" />
|
||||
<option name="screenX" value="1080" />
|
||||
<option name="screenY" value="2340" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="33" />
|
||||
<option name="brand" value="google" />
|
||||
<option name="codename" value="felix" />
|
||||
<option name="id" value="felix" />
|
||||
<option name="manufacturer" value="Google" />
|
||||
<option name="name" value="Pixel Fold" />
|
||||
<option name="screenDensity" value="420" />
|
||||
<option name="screenX" value="2208" />
|
||||
<option name="screenY" value="1840" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="google" />
|
||||
<option name="codename" value="felix" />
|
||||
<option name="id" value="felix" />
|
||||
<option name="manufacturer" value="Google" />
|
||||
<option name="name" value="Pixel Fold" />
|
||||
<option name="screenDensity" value="420" />
|
||||
<option name="screenX" value="2208" />
|
||||
<option name="screenY" value="1840" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="33" />
|
||||
<option name="brand" value="google" />
|
||||
<option name="codename" value="felix_camera" />
|
||||
<option name="id" value="felix_camera" />
|
||||
<option name="manufacturer" value="Google" />
|
||||
<option name="name" value="Pixel Fold (Camera-enabled)" />
|
||||
<option name="screenDensity" value="420" />
|
||||
<option name="screenX" value="2208" />
|
||||
<option name="screenY" value="1840" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="33" />
|
||||
<option name="brand" value="samsung" />
|
||||
<option name="codename" value="gts8uwifi" />
|
||||
<option name="id" value="gts8uwifi" />
|
||||
<option name="manufacturer" value="Samsung" />
|
||||
<option name="name" value="Galaxy Tab S8 Ultra" />
|
||||
<option name="screenDensity" value="320" />
|
||||
<option name="screenX" value="1848" />
|
||||
<option name="screenY" value="2960" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="google" />
|
||||
<option name="codename" value="husky" />
|
||||
<option name="id" value="husky" />
|
||||
<option name="manufacturer" value="Google" />
|
||||
<option name="name" value="Pixel 8 Pro" />
|
||||
<option name="screenDensity" value="390" />
|
||||
<option name="screenX" value="1008" />
|
||||
<option name="screenY" value="2244" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="30" />
|
||||
<option name="brand" value="motorola" />
|
||||
<option name="codename" value="java" />
|
||||
<option name="id" value="java" />
|
||||
<option name="manufacturer" value="Motorola" />
|
||||
<option name="name" value="G20" />
|
||||
<option name="screenDensity" value="280" />
|
||||
<option name="screenX" value="720" />
|
||||
<option name="screenY" value="1600" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="google" />
|
||||
<option name="codename" value="komodo" />
|
||||
<option name="id" value="komodo" />
|
||||
<option name="manufacturer" value="Google" />
|
||||
<option name="name" value="Pixel 9 Pro XL" />
|
||||
<option name="screenDensity" value="360" />
|
||||
<option name="screenX" value="1008" />
|
||||
<option name="screenY" value="2244" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="33" />
|
||||
<option name="brand" value="google" />
|
||||
<option name="codename" value="lynx" />
|
||||
<option name="id" value="lynx" />
|
||||
<option name="manufacturer" value="Google" />
|
||||
<option name="name" value="Pixel 7a" />
|
||||
<option name="screenDensity" value="420" />
|
||||
<option name="screenX" value="1080" />
|
||||
<option name="screenY" value="2400" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="31" />
|
||||
<option name="brand" value="google" />
|
||||
<option name="codename" value="oriole" />
|
||||
<option name="id" value="oriole" />
|
||||
<option name="manufacturer" value="Google" />
|
||||
<option name="name" value="Pixel 6" />
|
||||
<option name="screenDensity" value="420" />
|
||||
<option name="screenX" value="1080" />
|
||||
<option name="screenY" value="2400" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="33" />
|
||||
<option name="brand" value="google" />
|
||||
<option name="codename" value="panther" />
|
||||
<option name="id" value="panther" />
|
||||
<option name="manufacturer" value="Google" />
|
||||
<option name="name" value="Pixel 7" />
|
||||
<option name="screenDensity" value="420" />
|
||||
<option name="screenX" value="1080" />
|
||||
<option name="screenY" value="2400" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="samsung" />
|
||||
<option name="codename" value="q5q" />
|
||||
<option name="id" value="q5q" />
|
||||
<option name="manufacturer" value="Samsung" />
|
||||
<option name="name" value="Galaxy Z Fold5" />
|
||||
<option name="screenDensity" value="420" />
|
||||
<option name="screenX" value="1812" />
|
||||
<option name="screenY" value="2176" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="samsung" />
|
||||
<option name="codename" value="q6q" />
|
||||
<option name="id" value="q6q" />
|
||||
<option name="manufacturer" value="Samsung" />
|
||||
<option name="name" value="Galaxy Z Fold6" />
|
||||
<option name="screenDensity" value="420" />
|
||||
<option name="screenX" value="1856" />
|
||||
<option name="screenY" value="2160" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="30" />
|
||||
<option name="brand" value="google" />
|
||||
<option name="codename" value="r11" />
|
||||
<option name="id" value="r11" />
|
||||
<option name="manufacturer" value="Google" />
|
||||
<option name="name" value="Pixel Watch" />
|
||||
<option name="screenDensity" value="320" />
|
||||
<option name="screenX" value="384" />
|
||||
<option name="screenY" value="384" />
|
||||
<option name="type" value="WEAR_OS" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="30" />
|
||||
<option name="brand" value="google" />
|
||||
<option name="codename" value="redfin" />
|
||||
<option name="id" value="redfin" />
|
||||
<option name="manufacturer" value="Google" />
|
||||
<option name="name" value="Pixel 5" />
|
||||
<option name="screenDensity" value="440" />
|
||||
<option name="screenX" value="1080" />
|
||||
<option name="screenY" value="2340" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="google" />
|
||||
<option name="codename" value="shiba" />
|
||||
<option name="id" value="shiba" />
|
||||
<option name="manufacturer" value="Google" />
|
||||
<option name="name" value="Pixel 8" />
|
||||
<option name="screenDensity" value="420" />
|
||||
<option name="screenX" value="1080" />
|
||||
<option name="screenY" value="2400" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="33" />
|
||||
<option name="brand" value="google" />
|
||||
<option name="codename" value="tangorpro" />
|
||||
<option name="id" value="tangorpro" />
|
||||
<option name="manufacturer" value="Google" />
|
||||
<option name="name" value="Pixel Tablet" />
|
||||
<option name="screenDensity" value="320" />
|
||||
<option name="screenX" value="1600" />
|
||||
<option name="screenY" value="2560" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="google" />
|
||||
<option name="codename" value="tokay" />
|
||||
<option name="id" value="tokay" />
|
||||
<option name="manufacturer" value="Google" />
|
||||
<option name="name" value="Pixel 9" />
|
||||
<option name="screenDensity" value="420" />
|
||||
<option name="screenX" value="1080" />
|
||||
<option name="screenY" value="2424" />
|
||||
</PersistentDeviceSelectionData>
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
@@ -181,24 +181,6 @@ class LectureNote(
|
||||
}
|
||||
}
|
||||
|
||||
var lectureNotes: HashMap<Int, LectureNote> = hashMapOf()
|
||||
var selectedLecture: Int = 0
|
||||
|
||||
var selectedDay: Int = 0
|
||||
var dayEndString: String = ""
|
||||
|
||||
var isChecked: Boolean = true
|
||||
|
||||
const val apiBaseUrl = "https://aplikace.skolaonline.cz/solapi/api"
|
||||
const val tokenUrl = "$apiBaseUrl/connect/token"
|
||||
var token: String = ""
|
||||
const val userDataUrl = "$apiBaseUrl/v1/user"
|
||||
var userData: String = ""
|
||||
//var studentId: String = ""
|
||||
const val timeTableUrl = "$apiBaseUrl/v1/timeTable"
|
||||
var syid = "" // school year id
|
||||
var marksUrl = "$apiBaseUrl/v1/students/abc/marks/list?SemesterId=$syid"
|
||||
|
||||
class Subject {
|
||||
lateinit var name: String
|
||||
lateinit var place: String
|
||||
@@ -284,48 +266,62 @@ enum class ScreenElement {
|
||||
}
|
||||
|
||||
class Global {
|
||||
lateinit var token: String
|
||||
lateinit var userData: JSONObject
|
||||
lateinit var timetable: List<Day>
|
||||
lateinit var timetableJSON: JSONObject
|
||||
lateinit var marks: MutableMap<String, MutableList<Mark>>
|
||||
lateinit var marksJSON: JSONObject
|
||||
lateinit var studentClass: String
|
||||
lateinit var marks: MutableMap<String, MutableList<Mark>>
|
||||
lateinit var settings: SettingsData
|
||||
lateinit var studentId: String
|
||||
lateinit var fileDir: File
|
||||
|
||||
lateinit var token: String
|
||||
lateinit var studentClass: String
|
||||
lateinit var studentId: String
|
||||
|
||||
var userData: JSONObject = JSONObject()
|
||||
var timetable: List<Day> = listOf()
|
||||
var lectureNotes: HashMap<Int, LectureNote> = hashMapOf()
|
||||
|
||||
var username: String = ""
|
||||
var password: String = ""
|
||||
var isAPISetUp: Boolean = false
|
||||
|
||||
var noSignInBackHandle: Boolean = false
|
||||
var lectureNotes: HashMap<Int, LectureNote> = hashMapOf()
|
||||
var status by mutableStateOf("")
|
||||
|
||||
var selectedLecture: Int = 0
|
||||
var currentLectureNumber: Int = 0
|
||||
|
||||
var currentScreen by mutableStateOf(Screen.Main)
|
||||
var currentScreenElement by mutableStateOf(ScreenElement.Timetable)
|
||||
|
||||
var status by mutableStateOf("")
|
||||
|
||||
var isAPISetUp by mutableStateOf(false)
|
||||
var launched by mutableStateOf(false)
|
||||
var refreshed by mutableStateOf(false)
|
||||
|
||||
inner class FilePaths {
|
||||
val accountData: String = "account_data.txt"
|
||||
val timeTable: String = "timetable.json"
|
||||
val timetable: String = "timetable.json"
|
||||
val userData: String = "userdata.json"
|
||||
val marks: String = "marks.json"
|
||||
val settings: String = "settings.txt"
|
||||
val lectureNotes: String = "lecture_notes.csv"
|
||||
}
|
||||
val filePaths = FilePaths()
|
||||
|
||||
inner class APIEndPoints {
|
||||
val apiBaseUrl = "https://aplikace.skolaonline.cz/solapi/api"
|
||||
val tokenUrl = "$apiBaseUrl/connect/token"
|
||||
lateinit var token: String
|
||||
val userDataUrl = "$apiBaseUrl/v1/user"
|
||||
lateinit var userData: String
|
||||
val timeTableUrl = "$apiBaseUrl/v1/timeTable"
|
||||
lateinit var marksUrl: String
|
||||
val apiBase = "https://aplikace.skolaonline.cz/solapi/api"
|
||||
val token = "$apiBase/connect/token"
|
||||
val userData = "$apiBase/v1/user"
|
||||
val timetable = "$apiBase/v1/timeTable"
|
||||
var marks: String = "$apiBase/v1/students/<student id>/marks/list"
|
||||
}
|
||||
val apiEndPoints = APIEndPoints()
|
||||
|
||||
inner class Dimens {
|
||||
val borderWidth = 5.dp
|
||||
val roundedCorner = 8.dp
|
||||
}
|
||||
val dimens = Dimens()
|
||||
|
||||
inner class Modifiers {
|
||||
var bar = Modifier
|
||||
.fillMaxWidth()
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.odweta.solon
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
@@ -9,8 +10,10 @@ import kotlinx.coroutines.launch
|
||||
import org.json.JSONObject
|
||||
|
||||
fun launchStart(ctx: Context) {
|
||||
global.launched = false
|
||||
if (Account.haveSaved()) {
|
||||
if (Util.internetAvail(ctx)) {
|
||||
global.currentScreen = Screen.Splash
|
||||
remoteLoad(ctx)
|
||||
} else {
|
||||
localLoad(ctx)
|
||||
@@ -22,34 +25,38 @@ fun launchStart(ctx: Context) {
|
||||
}
|
||||
|
||||
fun remoteLoad(ctx: Context) {
|
||||
var remoteTimetable: JSONObject
|
||||
var remoteMarks: JSONObject
|
||||
Log.d("debug", "remoteLoad called")
|
||||
if (!global.isAPISetUp) {
|
||||
CoroutineScope(Dispatchers.IO)
|
||||
.launch {
|
||||
Network.setupAPI()
|
||||
remoteTimetable = Network.getTimeTable()
|
||||
global.timetableJSON = remoteTimetable
|
||||
remoteMarks = Network.getMarks()
|
||||
global.marksJSON = remoteMarks
|
||||
global.timetableJSON = Network.getTimeTable()
|
||||
global.marksJSON = Network.getMarks()
|
||||
|
||||
launchContinue(
|
||||
ctx,
|
||||
remoteTimetable,
|
||||
remoteMarks
|
||||
)
|
||||
}
|
||||
} else {
|
||||
launchContinue(
|
||||
ctx,
|
||||
global.timetableJSON,
|
||||
global.marksJSON
|
||||
)
|
||||
}
|
||||
} else {
|
||||
Log.d("debug", "API set up, continuing")
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
launchContinue(
|
||||
ctx,
|
||||
Network.getTimeTable(),
|
||||
Network.getMarks()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun localLoad(ctx: Context) {
|
||||
val localTimetable = JSONObject(Util.fileToString(timeTableFilePath))
|
||||
global.userData = JSONObject(Util.fileToString(global.filePaths.userData))
|
||||
global.studentId = Network.getStudentId()
|
||||
global.studentClass = Network.getStudentClass()
|
||||
global.apiEndPoints.marks = "${global.apiEndPoints.apiBase}/v1/students/${global.studentId}/marks/list"
|
||||
val localTimetable = JSONObject(Util.fileToString(global.filePaths.timetable))
|
||||
val localMarks = JSONObject(Util.fileToString(marksFilePath))
|
||||
|
||||
launchContinue(
|
||||
@@ -78,10 +85,16 @@ fun launchContinue(
|
||||
val lectureNotes = Util.fileToString(global.filePaths.lectureNotes)
|
||||
Parsing.parseLectureNotes(lectureNotes)
|
||||
|
||||
Log.d("debug", "parsed the things")
|
||||
|
||||
// listen for internet availability in case of disconnection
|
||||
if (!internetAwaitListenerRunning)
|
||||
setOnInternetAvailListener(ctx)
|
||||
|
||||
global.launched = true
|
||||
global.refreshed = true
|
||||
refreshButtonContentColor.value = Color.White
|
||||
|
||||
// show the default (main) screen
|
||||
global.currentScreen = Screen.Main
|
||||
|
||||
@@ -90,6 +103,8 @@ fun launchContinue(
|
||||
|
||||
// show the full name of the user in the toolbar as a status
|
||||
statusFactory.show(StatusType.NameRole)
|
||||
|
||||
Log.d("debug", "done and should show nameRole status")
|
||||
}
|
||||
|
||||
private fun setOnInternetAvailListener(ctx: Context) {
|
||||
|
||||
@@ -31,7 +31,7 @@ class MainActivity : ComponentActivity() {
|
||||
setContent {
|
||||
SolonTheme {
|
||||
when (global.currentScreen) {
|
||||
Screen.Main -> MainScreen()
|
||||
Screen.Main -> if (global.launched) MainScreen()
|
||||
Screen.Splash -> SplashScreen()
|
||||
Screen.SignIn -> SignInScreen()
|
||||
}
|
||||
|
||||
@@ -27,6 +27,8 @@ import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.odweta.solon.ui.theme.PastelYellow
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
private var timetableColor: MutableState<Color> = mutableStateOf(PastelYellow)
|
||||
private var marksColor: MutableState<Color> = mutableStateOf(Color.White)
|
||||
@@ -47,6 +49,7 @@ fun NavbarScreen() {
|
||||
Button(
|
||||
onClick = {
|
||||
remoteLoad(ctx)
|
||||
statusFactory.show(StatusType.Loading)
|
||||
refreshButtonContentColor.value = PastelYellow
|
||||
},
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
package com.odweta.solon
|
||||
|
||||
import android.util.Log
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import okhttp3.FormBody
|
||||
import okhttp3.Request
|
||||
import org.json.JSONException
|
||||
@@ -13,7 +10,7 @@ class Network {
|
||||
companion object {
|
||||
fun getToken(): String {
|
||||
val request = Request.Builder()
|
||||
.url(global.apiEndPoints.tokenUrl)
|
||||
.url(global.apiEndPoints.token)
|
||||
.header("Content-Type", "application/x-www-form-urlencoded")
|
||||
.post(
|
||||
FormBody.Builder()
|
||||
@@ -57,7 +54,16 @@ class Network {
|
||||
}
|
||||
global.userData = getUserData()
|
||||
Util.saveStringToFile(global.filePaths.userData, global.userData.toString())
|
||||
global.studentClass = if (!Parsing.userIsParent()) {
|
||||
global.studentClass = getStudentClass()
|
||||
global.studentId = getStudentId()
|
||||
|
||||
global.apiEndPoints.marks = "${global.apiEndPoints.apiBase}/v1/students/${global.studentId}/marks/list"
|
||||
|
||||
global.isAPISetUp = true
|
||||
}
|
||||
|
||||
fun getStudentClass(): String { // TODO: move to Parsing
|
||||
return if (!Parsing.userIsParent()) {
|
||||
JSONObject(
|
||||
Util.fileToString(global.filePaths.userData)
|
||||
).getJSONObject("class").getString("name")
|
||||
@@ -67,14 +73,9 @@ class Network {
|
||||
Util.fileToString(global.filePaths.userData)
|
||||
).getJSONArray("children").getJSONObject(0).getString("className")
|
||||
}
|
||||
global.studentId = getStudentId()
|
||||
|
||||
global.apiEndPoints.marksUrl = "$apiBaseUrl/v1/students/${global.studentId}/marks/list"
|
||||
|
||||
global.isAPISetUp = true
|
||||
}
|
||||
|
||||
fun getStudentId(): String {
|
||||
fun getStudentId(): String { // TODO: move to Parsing
|
||||
return if (!Parsing.userIsParent()) {
|
||||
global.userData.getString("personID")
|
||||
} else {
|
||||
@@ -86,7 +87,7 @@ class Network {
|
||||
|
||||
fun getUserData(): JSONObject {
|
||||
val request = Request.Builder()
|
||||
.url(global.apiEndPoints.userDataUrl)
|
||||
.url(global.apiEndPoints.userData)
|
||||
.header("Content-Type", "application/x-www-form-urlencoded")
|
||||
.header("Authorization", "Bearer ${global.token}") // using Bearer auth token
|
||||
.get()
|
||||
@@ -105,8 +106,8 @@ class Network {
|
||||
|
||||
fun getTimeTable(): JSONObject {
|
||||
val userIsParent = Parsing.userIsParent()
|
||||
val url = if (!userIsParent) global.apiEndPoints.timeTableUrl
|
||||
else "${global.apiEndPoints.timeTableUrl}?studentId=${global.studentId}"
|
||||
val url = if (!userIsParent) global.apiEndPoints.timetable
|
||||
else "${global.apiEndPoints.timetable}?studentId=${global.studentId}"
|
||||
|
||||
val request = Request.Builder()
|
||||
.url(url)
|
||||
@@ -127,7 +128,7 @@ class Network {
|
||||
|
||||
fun getMarks(): JSONObject {
|
||||
val request = Request.Builder()
|
||||
.url(global.apiEndPoints.marksUrl)
|
||||
.url(global.apiEndPoints.marks)
|
||||
.header("Content-Type", "application/x-www-form-urlencoded")
|
||||
.header("Authorization", "Bearer ${global.token}")
|
||||
.get()
|
||||
|
||||
@@ -47,29 +47,26 @@ class Parsing {
|
||||
}
|
||||
|
||||
fun userIsParent(): Boolean {
|
||||
return if (userData != "")
|
||||
JSONObject(userData).getString("userType") == "parent"
|
||||
return if (global.userData != JSONObject())
|
||||
global.userData.getString("userType") == "parent"
|
||||
else false
|
||||
}
|
||||
|
||||
fun parseTimetable(jsonString: JSONObject): List<Day> {
|
||||
Log.d("debug", "gotten json: $jsonString")
|
||||
val jsonObject = jsonString
|
||||
|
||||
fun parseTimetable(json: JSONObject): List<Day> {
|
||||
/*
|
||||
* return a List that looks like this:
|
||||
* [<name>, <date>, [<subj_name>, <subj_place>, <teacher>, <substitute>, <number>, <start_time>, <end_time>]]
|
||||
* ["Po", "8.1.", ["D", "207", "Strakova S.", 0, 1, "08:00", "08:45" ]]
|
||||
*/
|
||||
|
||||
val week = mutableListOf<Day>()
|
||||
val timetable = mutableListOf<Day>()
|
||||
|
||||
if (jsonObject.has("error")) {
|
||||
return week
|
||||
if (json.has("error")) {
|
||||
return timetable
|
||||
}
|
||||
|
||||
// Access the "body" array from the main JSON object
|
||||
val bodyArray = jsonObject.getJSONArray("days")
|
||||
val bodyArray = json.getJSONArray("days")
|
||||
|
||||
// Convert the JSON array to a list of JSON objects
|
||||
val jsonObjectList = mutableListOf<JSONObject>()
|
||||
@@ -88,8 +85,12 @@ class Parsing {
|
||||
.split("-")
|
||||
|
||||
// remove leading zeros
|
||||
while (dayStr[0] == '0') { dayStr = dayStr.slice(1..<dayStr.length) }
|
||||
while (monthStr[0] == '0') { monthStr = monthStr.slice(1..<monthStr.length) }
|
||||
while (dayStr[0] == '0') {
|
||||
dayStr = dayStr.slice(1..<dayStr.length)
|
||||
}
|
||||
while (monthStr[0] == '0') {
|
||||
monthStr = monthStr.slice(1..<monthStr.length)
|
||||
}
|
||||
|
||||
// format it into a string that is readable
|
||||
val date = "$dayStr. $monthStr."
|
||||
@@ -130,35 +131,34 @@ class Parsing {
|
||||
if (type != "SUPLOVANI" && type != "ROZVRH") {
|
||||
when (kind) {
|
||||
"ZRUSENI_VYUKY_ROZVRH" -> {
|
||||
subject.name = subj.get("title").toString()
|
||||
subject.name = subj.getString("title")
|
||||
subject.place = ""
|
||||
subject.teacher = ""
|
||||
subject.substitute = "2" // 2 means school event
|
||||
|
||||
val hourspan = subj.getJSONArray("detailHours").length()
|
||||
subject.number = "1 - $hourspan"
|
||||
subject.start = subj.get("beginTime").toString()
|
||||
subject.start = subj.getString("beginTime")
|
||||
subject.start = subject.start.slice(0..subject.start.length - 4)
|
||||
subject.end = subj.get("endTime").toString()
|
||||
subject.end = subj.getString("endTime")
|
||||
subject.end = subject.end.slice(0..subject.end.length - 4)
|
||||
|
||||
subjects.add(subject)
|
||||
}
|
||||
|
||||
"S_NAHRADOU_SKOL_AKCE" -> eventLecture(subject, subj, subjects)
|
||||
"S_NAHRADOU_VYUKA" -> eventLecture(subject, subj, subjects)
|
||||
}
|
||||
} else {
|
||||
subject.name = subj.getJSONObject("subject").get("abbrev").toString()
|
||||
subject.name = subj.getJSONObject("subject").getString("abbrev")
|
||||
subject.place =
|
||||
subj.getJSONArray("rooms").getJSONObject(0).get("abbrev").toString()
|
||||
subject.teacher = "" +
|
||||
"${
|
||||
subj.getJSONArray("teachers").getJSONObject(0).get("name")
|
||||
} " +
|
||||
"${
|
||||
subj.getJSONArray("rooms").getJSONObject(0).getString("abbrev")
|
||||
subject.teacher = if (subj.getJSONArray("teachers").length() > 0) {
|
||||
subj.getJSONArray("teachers").getJSONObject(0)
|
||||
.get("surname")
|
||||
}"
|
||||
.getString("fullName") // TODO: keep in mind that fullName might not be a valid field (name and surname are!)
|
||||
} else {
|
||||
""
|
||||
}
|
||||
subject.substitute = when (type) {
|
||||
"ROZVRH" -> "0"
|
||||
"SUPLOVANI" -> "1"
|
||||
@@ -313,15 +313,17 @@ class Parsing {
|
||||
prevSubject = s
|
||||
}
|
||||
|
||||
nextSubjects[nextSubjects.size-1].start = day.subjects[day.subjects.size-1].start
|
||||
nextSubjects[nextSubjects.size - 1].start =
|
||||
day.subjects[day.subjects.size - 1].start
|
||||
nextSubjects[nextSubjects.size - 1].end = day.subjects[day.subjects.size - 1].end
|
||||
|
||||
day.subjects = nextSubjects
|
||||
|
||||
week.add(day)
|
||||
timetable.add(day)
|
||||
}
|
||||
|
||||
return week
|
||||
Log.d("debug", "timetable: $timetable")
|
||||
return timetable
|
||||
}
|
||||
|
||||
fun parseMarks(jsonString: JSONObject): MutableMap<String, MutableList<Mark>> {
|
||||
|
||||
@@ -39,20 +39,21 @@ import kotlinx.coroutines.launch
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
||||
private var buttonText: MutableState<String> = mutableStateOf("Přihlásit se")
|
||||
private var buttonText by mutableStateOf("Přihlásit se")
|
||||
|
||||
private fun changeButtonText(s: String) {
|
||||
buttonText.value = s
|
||||
buttonText = s
|
||||
}
|
||||
|
||||
fun signInButtonCallback(ctx: Context, coscope: CoroutineScope, buttonText: String, usernameText: String, passwordText: String) {
|
||||
fun signInButtonCallback(ctx: Context, usernameText: String, passwordText: String) {
|
||||
username = usernameText
|
||||
password = passwordText
|
||||
val acc = Account(username, password, 0)
|
||||
var checked = false
|
||||
|
||||
coscope.launch {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
while (!checked) {
|
||||
delay(300)
|
||||
changeButtonText("Přihlašování")
|
||||
@@ -85,7 +86,7 @@ fun signInButtonCallback(ctx: Context, coscope: CoroutineScope, buttonText: Stri
|
||||
changeButtonText("Přihlásit se")
|
||||
}
|
||||
|
||||
coscope.launch {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
val valid = Account.isValid(acc)
|
||||
|
||||
checked = true
|
||||
@@ -108,9 +109,7 @@ fun signInButtonCallback(ctx: Context, coscope: CoroutineScope, buttonText: Stri
|
||||
fun SignInScreen() {
|
||||
// handle the back gesture (back swipe form side or back button on bottom android navbar)
|
||||
if (!global.noSignInBackHandle) {
|
||||
BackHandler {
|
||||
global.currentScreen = Screen.Main
|
||||
}
|
||||
BackHandler { global.currentScreen = Screen.Main }
|
||||
}
|
||||
|
||||
var usernameText by remember { mutableStateOf("") }
|
||||
@@ -200,7 +199,7 @@ fun SignInScreen() {
|
||||
|
||||
Button(
|
||||
onClick = {
|
||||
signInButtonCallback(ctx, coscope, buttonText.value, usernameText, passwordText)
|
||||
signInButtonCallback(ctx, usernameText, passwordText)
|
||||
},
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
contentColor = Color.White,
|
||||
@@ -215,7 +214,7 @@ fun SignInScreen() {
|
||||
.width(230.dp)
|
||||
) {
|
||||
Text(
|
||||
text = buttonText.value,
|
||||
text = buttonText,
|
||||
fontSize = 23.sp
|
||||
)
|
||||
}
|
||||
|
||||
@@ -40,12 +40,7 @@ fun SplashScreen() {
|
||||
|
||||
AndroidView(
|
||||
modifier = Modifier.size(200.dp),
|
||||
factory = { context: Context ->
|
||||
ImageView(context).apply {
|
||||
// Set a placeholder if needed
|
||||
// setImageResource(R.drawable.placeholder)
|
||||
}
|
||||
},
|
||||
factory = { context: Context -> ImageView(context) },
|
||||
update = { imageView ->
|
||||
Glide.with(imageView.context)
|
||||
.load(R.drawable.loading)
|
||||
|
||||
@@ -69,19 +69,16 @@ import java.time.LocalDate
|
||||
import java.time.LocalTime
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
var showDetailDialog = mutableStateOf(false)
|
||||
var showDetailDialog by mutableStateOf(false)
|
||||
|
||||
@Composable
|
||||
fun TimetableScreen() {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize(),
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentAlignment = Alignment.BottomCenter
|
||||
) {
|
||||
DayPager()
|
||||
if (showDetailDialog.value) {
|
||||
DetailDialog()
|
||||
}
|
||||
if (showDetailDialog) DetailDialog()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +87,7 @@ fun TimetableScreen() {
|
||||
@Composable
|
||||
fun DetailDialog() {
|
||||
Dialog(
|
||||
onDismissRequest = { showDetailDialog.value = false }, // Close the dialog on dismiss
|
||||
onDismissRequest = { showDetailDialog = false }, // Close the dialog on dismiss
|
||||
properties = DialogProperties(
|
||||
dismissOnBackPress = true,
|
||||
dismissOnClickOutside = true
|
||||
@@ -102,7 +99,7 @@ fun DetailDialog() {
|
||||
.padding(horizontal = 20.dp)
|
||||
.background(
|
||||
color = Color.Black,
|
||||
shape = RoundedCornerShape(roundedCornerDimen)
|
||||
shape = RoundedCornerShape(global.dimens.roundedCorner)
|
||||
)
|
||||
) {
|
||||
Column(
|
||||
@@ -110,9 +107,9 @@ fun DetailDialog() {
|
||||
) {
|
||||
Text(
|
||||
text = "" +
|
||||
lectureNotes[selectedLecture]?.number.toString() +
|
||||
global.lectureNotes[global.selectedLecture]?.number.toString() +
|
||||
" – " +
|
||||
lectureNotes[selectedLecture]?.lectureName.toString(),
|
||||
global.lectureNotes[global.selectedLecture]?.lectureName.toString(),
|
||||
color = Color.White,
|
||||
textAlign = TextAlign.Left,
|
||||
modifier = Modifier.padding(top = 10.dp)
|
||||
@@ -125,7 +122,7 @@ fun DetailDialog() {
|
||||
Button(
|
||||
modifier = Modifier.background(
|
||||
color = Color.Black,
|
||||
shape = RoundedCornerShape(roundedCornerDimen)
|
||||
shape = RoundedCornerShape(global.dimens.roundedCorner)
|
||||
),
|
||||
onClick = { isExpanded = true },
|
||||
colors = ButtonColors(
|
||||
@@ -135,7 +132,7 @@ fun DetailDialog() {
|
||||
disabledContentColor = Color.White
|
||||
)
|
||||
) {
|
||||
val type = when (lectureNotes[selectedLecture]?.type?.value) {
|
||||
val type = when (global.lectureNotes[global.selectedLecture]?.type?.value) {
|
||||
LectureNoteType.Normal -> "Normální"
|
||||
LectureNoteType.Writing -> "Písemný test"
|
||||
LectureNoteType.Speaking -> "Ústní zkoušení"
|
||||
@@ -160,7 +157,7 @@ fun DetailDialog() {
|
||||
enabled = true,
|
||||
onClick = {
|
||||
isExpanded = false
|
||||
lectureNotes[selectedLecture]?.type?.value = LectureNoteType.Normal
|
||||
global.lectureNotes[global.selectedLecture]?.type?.value = LectureNoteType.Normal
|
||||
Util.saveLectureNotes()
|
||||
},
|
||||
text = { Text("Normální poznámka", color = Color.White) }
|
||||
@@ -170,7 +167,7 @@ fun DetailDialog() {
|
||||
enabled = true,
|
||||
onClick = {
|
||||
isExpanded = false
|
||||
lectureNotes[selectedLecture]?.type?.value = LectureNoteType.Writing
|
||||
global.lectureNotes[global.selectedLecture]?.type?.value = LectureNoteType.Writing
|
||||
Util.saveLectureNotes()
|
||||
},
|
||||
text = { Text("Písemný test", color = Color.White) }
|
||||
@@ -180,7 +177,7 @@ fun DetailDialog() {
|
||||
enabled = true,
|
||||
onClick = {
|
||||
isExpanded = false
|
||||
lectureNotes[selectedLecture]?.type?.value = LectureNoteType.Speaking
|
||||
global.lectureNotes[global.selectedLecture]?.type?.value = LectureNoteType.Speaking
|
||||
Util.saveLectureNotes()
|
||||
},
|
||||
text = { Text("Ústní zkoušení", color = Color.White) }
|
||||
@@ -190,7 +187,7 @@ fun DetailDialog() {
|
||||
enabled = true,
|
||||
onClick = {
|
||||
isExpanded = false
|
||||
lectureNotes[selectedLecture]?.type?.value = LectureNoteType.Other
|
||||
global.lectureNotes[global.selectedLecture]?.type?.value = LectureNoteType.Other
|
||||
Util.saveLectureNotes()
|
||||
},
|
||||
text = { Text("Jiné", color = Color.White) }
|
||||
@@ -200,9 +197,9 @@ fun DetailDialog() {
|
||||
////////////////////////////////////////////////
|
||||
|
||||
TextField(
|
||||
value = lectureNotes[selectedLecture]?.note?.value ?: "",
|
||||
value = global.lectureNotes[global.selectedLecture]?.note?.value ?: "",
|
||||
onValueChange = { newText: String ->
|
||||
lectureNotes[selectedLecture]?.note?.value = newText
|
||||
global.lectureNotes[global.selectedLecture]?.note?.value = newText
|
||||
Util.saveLectureNotes()
|
||||
},
|
||||
singleLine = true,
|
||||
@@ -228,12 +225,12 @@ fun DetailDialog() {
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
fun DayPager() {
|
||||
val pagerState = rememberPagerState(pageCount = { days.size })
|
||||
val pagerState = rememberPagerState(pageCount = { if (global.timetable.isNotEmpty()) global.timetable.size else 6 }) // FIXME
|
||||
HorizontalPager(
|
||||
state = pagerState,
|
||||
modifier = Modifier.fillMaxSize()
|
||||
) { pageIndex ->
|
||||
DayScreen(days[pageIndex])
|
||||
DayScreen(global.timetable[pageIndex])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,7 +284,7 @@ fun subjectModifier(d: Day, s: Subject, lectureNumber: Int): Modifier {
|
||||
val now = LocalTime.now()
|
||||
|
||||
if (dateParsed == todayDate && isTimeBetween(now, startTimeParsed, endTimeParsed)) {
|
||||
currentLectureNumber = lectureNumber
|
||||
global.currentLectureNumber = lectureNumber
|
||||
}
|
||||
|
||||
val m = if (settings.useAmoledMode.checked.value) {
|
||||
@@ -295,9 +292,9 @@ fun subjectModifier(d: Day, s: Subject, lectureNumber: Int): Modifier {
|
||||
.fillMaxWidth()
|
||||
.height(70.dp)
|
||||
.border(
|
||||
width = borderWidthDimen,
|
||||
width = global.dimens.borderWidth,
|
||||
color = getSubjectColor(s, false), // decide on the color (transparent)
|
||||
shape = RoundedCornerShape(roundedCornerDimen)
|
||||
shape = RoundedCornerShape(global.dimens.roundedCorner)
|
||||
)
|
||||
} else {
|
||||
Modifier
|
||||
@@ -305,15 +302,15 @@ fun subjectModifier(d: Day, s: Subject, lectureNumber: Int): Modifier {
|
||||
.height(70.dp)
|
||||
.background(
|
||||
color = getSubjectColor(s, true), // decide on the color (transparent)
|
||||
shape = RoundedCornerShape(roundedCornerDimen)
|
||||
shape = RoundedCornerShape(global.dimens.roundedCorner)
|
||||
)
|
||||
}
|
||||
|
||||
return if (lectureNumber == currentLectureNumber && dateParsed == todayDate) {
|
||||
return if (lectureNumber == global.currentLectureNumber && dateParsed == todayDate) {
|
||||
m.border(
|
||||
width = borderWidthDimen,
|
||||
width = global.dimens.borderWidth,
|
||||
color = getSubjectColor(s, false),
|
||||
shape = RoundedCornerShape(roundedCornerDimen)
|
||||
shape = RoundedCornerShape(global.dimens.roundedCorner)
|
||||
)
|
||||
} else {
|
||||
m
|
||||
@@ -359,12 +356,12 @@ private fun DayScreen(day: Day) {
|
||||
.width(50.dp)
|
||||
.fillMaxHeight()
|
||||
.border(
|
||||
width = borderWidthDimen,
|
||||
width = global.dimens.borderWidth,
|
||||
color = getSubjectColor(
|
||||
subject,
|
||||
false
|
||||
),
|
||||
shape = RoundedCornerShape(roundedCornerDimen)
|
||||
shape = RoundedCornerShape(global.dimens.roundedCorner)
|
||||
)
|
||||
} else {
|
||||
Modifier
|
||||
@@ -375,7 +372,7 @@ private fun DayScreen(day: Day) {
|
||||
subject,
|
||||
true
|
||||
),
|
||||
shape = RoundedCornerShape(roundedCornerDimen)
|
||||
shape = RoundedCornerShape(global.dimens.roundedCorner)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -482,7 +479,7 @@ private fun DayScreen(day: Day) {
|
||||
if (settings.useSvobodaMode.checked.value) {
|
||||
if (
|
||||
subject.teacher == "Jindřich Svoboda" &&
|
||||
studentClass == "5. G"
|
||||
global.studentClass == "5. G"
|
||||
) {
|
||||
Image(
|
||||
painter = painterResource(R.drawable.spock),
|
||||
@@ -529,14 +526,14 @@ private fun DayScreen(day: Day) {
|
||||
.fillMaxSize()
|
||||
.zIndex(99f)
|
||||
.clickable {
|
||||
selectedLecture = lectureId
|
||||
showDetailDialog.value = true
|
||||
global.selectedLecture = lectureId
|
||||
showDetailDialog = true
|
||||
})
|
||||
|
||||
if (
|
||||
(lectureNotes[lectureId] != null && lectureNotes[lectureId]?.note?.value != "") ||
|
||||
(lectureNotes[lectureId] != null && lectureNotes[lectureId]?.type?.value != LectureNoteType.Normal) &&
|
||||
(lectureNotes[lectureId] != null && lectureNotes[lectureId]?.type?.value != LectureNoteType.Other)
|
||||
(global.lectureNotes[lectureId] != null && global.lectureNotes[lectureId]?.note?.value != "") ||
|
||||
(global.lectureNotes[lectureId] != null && global.lectureNotes[lectureId]?.type?.value != LectureNoteType.Normal) &&
|
||||
(global.lectureNotes[lectureId] != null && global.lectureNotes[lectureId]?.type?.value != LectureNoteType.Other)
|
||||
) {
|
||||
Icon(
|
||||
modifier = Modifier.padding(start = 3.dp, top = 1.dp),
|
||||
|
||||
@@ -6,6 +6,7 @@ import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
@@ -14,6 +15,10 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import org.json.JSONObject
|
||||
|
||||
@Composable
|
||||
@@ -48,10 +53,11 @@ fun ToolbarScreen() {
|
||||
|
||||
enum class StatusType {
|
||||
NameRole,
|
||||
NoInternet
|
||||
NoInternet,
|
||||
Loading
|
||||
}
|
||||
|
||||
interface StatusFactoryInterface {
|
||||
private interface StatusFactoryInterface {
|
||||
fun show(type: StatusType)
|
||||
}
|
||||
|
||||
@@ -70,6 +76,25 @@ object StatusFactory: StatusFactoryInterface {
|
||||
StatusType.NoInternet -> {
|
||||
showStatus("Bez připojení k internetu.")
|
||||
}
|
||||
StatusType.Loading -> {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
global.refreshed = false
|
||||
val anim = listOf(
|
||||
"Přihlašování",
|
||||
"Přihlašování.",
|
||||
"Přihlašování..",
|
||||
"Přihlašování...",
|
||||
"Přihlašování..",
|
||||
"Přihlašování."
|
||||
)
|
||||
var i = 0
|
||||
while (!global.refreshed) {
|
||||
if (i == anim.size) i = 0
|
||||
showStatus(anim[i++])
|
||||
delay(300)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,8 +280,8 @@ class Util {
|
||||
note += ",${parts[part]}"
|
||||
}
|
||||
|
||||
lectureNotes[id]?.note = mutableStateOf(note)
|
||||
lectureNotes[id]?.type = mutableStateOf(type)
|
||||
global.lectureNotes[id]?.note = mutableStateOf(note)
|
||||
global.lectureNotes[id]?.type = mutableStateOf(type)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -301,7 +301,7 @@ class Util {
|
||||
for (day in days) {
|
||||
for ((subjectIndex, subject) in day.subjects.withIndex()) {
|
||||
val id = getLectureId(day.date, subjectIndex)
|
||||
lectureNotes[id] = LectureNote(
|
||||
global.lectureNotes[id] = LectureNote(
|
||||
id = id,
|
||||
type = mutableStateOf(LectureNoteType.Normal),
|
||||
note = mutableStateOf(""),
|
||||
@@ -315,8 +315,8 @@ class Util {
|
||||
}
|
||||
|
||||
fun saveLectureNotes() {
|
||||
val toSave = lectureNotesToCsvString(lectureNotes)
|
||||
saveStringToFile(lectureNotesFilePath, toSave)
|
||||
val toSave = lectureNotesToCsvString(global.lectureNotes)
|
||||
saveStringToFile(global.filePaths.lectureNotes, toSave)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user