fixed app crashes and some other improvements

This commit is contained in:
Odweta
2024-12-30 17:31:27 +01:00
parent 6dae99d311
commit 1516a00841
14 changed files with 521 additions and 80 deletions
+340
View File
@@ -0,0 +1,340 @@
<?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>
+1 -1
View File
@@ -32,7 +32,7 @@ android {
applicationId = "com.odweta.solon"
minSdk = 28
targetSdk = 34
versionCode = 208
versionCode = 210
versionName = "2.3.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
Binary file not shown.
Binary file not shown.
+5 -5
View File
@@ -11,9 +11,9 @@
"type": "SINGLE",
"filters": [],
"attributes": [],
"versionCode": 1,
"versionName": "2.0",
"outputFile": "app-release.apk"
"versionCode": 208,
"versionName": "2.3.0",
"outputFile": "com.odweta.solon_2.3.0.apk"
}
],
"elementType": "File",
@@ -22,14 +22,14 @@
"minApi": 28,
"maxApi": 30,
"baselineProfiles": [
"baselineProfiles/1/app-release.dm"
"baselineProfiles/1/com.odweta.solon_2.3.0.dm"
]
},
{
"minApi": 31,
"maxApi": 2147483647,
"baselineProfiles": [
"baselineProfiles/0/app-release.dm"
"baselineProfiles/0/com.odweta.solon_2.3.0.dm"
]
}
],
@@ -1,5 +1,6 @@
package com.odweta.solon
import android.util.Log
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.json.JSONObject
@@ -8,17 +9,10 @@ import java.nio.charset.Charset
class Account(val username: String, val password: String, private val error: Int) {
companion object {
private fun parseAccountDataFile(file: File): Account {
val lines: List<String> = file.readLines()
if (lines.size >= 2) {
if (lines[0] != "" && lines[1] != "") {
private fun parseAccountDataFile(): Account {
val lines: List<String> = File(global.fileDir, global.filePaths.accountData).readLines()
return Account(lines[0], lines[1], 0)
}
}
return Account("", "", 1)
}
fun haveSaved(): Boolean {
/* check if a file exists
@@ -27,15 +21,17 @@ class Account(val username: String, val password: String, private val error: Int
*/
// check if file exists
val file = File(global.fileDir, global.filePaths.accountData)
return if (!file.exists()) {
return if (
!Util.fileExists(global.filePaths.accountData) ||
Util.fileIsEmpty(global.filePaths.accountData)
) {
// it does not exist
file.createNewFile()
File(global.fileDir, global.filePaths.accountData).createNewFile()
false
} else {
// it exists, so it shall be parsed
val acc: Account = parseAccountDataFile(file)
val acc: Account = parseAccountDataFile()
global.username = acc.username
global.password = acc.password
acc.error == 0
@@ -43,23 +39,20 @@ class Account(val username: String, val password: String, private val error: Int
}
fun save(acc: Account): Boolean {
return try {
val file = File(global.fileDir, global.filePaths.accountData)
file.writeText("${acc.username}\n${acc.password}\n", Charset.forName("UTF-8"))
true
} catch (e: Exception) {
false
}
val payload = "${acc.username}\n${acc.password}"
return Util.saveStringToFile(global.filePaths.accountData, payload)
}
suspend fun isValid(acc: Account): Boolean {
return withContext(Dispatchers.IO) {
fun isValid(acc: Account): Boolean {
global.username = acc.username
global.password = acc.password
val token = networkRequestFactory.perform(NetworkRequestType.Token).getString("token")
!JSONObject(token).has("error")
val tokenJSON = networkRequestFactory.perform(NetworkRequestType.Token)
return if (tokenJSON.has("token")) {
val token = tokenJSON.getString("token")
!token.contains("\"error\"")
} else {
false
}
}
}
@@ -76,7 +76,15 @@ fun String.toLectureNoteType(): LectureNoteType {
}
}
class LectureNote(id: Int, note: MutableState<String>, type: MutableState<LectureNoteType>, number: Int, lectureName: String) {
data class LectureNote(
var id: Int,
var note: MutableState<String> = mutableStateOf(""),
var type: MutableState<LectureNoteType> = mutableStateOf(LectureNoteType.Normal),
var number: Int,
var lectureName: String
)
class LectureNoteOLD(id: Int, note: MutableState<String>, type: MutableState<LectureNoteType>, number: Int, lectureName: String) {
var id: Int = 0
var note: MutableState<String> =
mutableStateOf("")
@@ -81,6 +81,7 @@ fun launchContinue(
global.settings = settingsData
// load the lecture notes
Util.loadLectureNotes()
Util.csvToLectureNotes()
// listen for internet availability in case of disconnection
@@ -14,12 +14,16 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.AutoAwesome
import androidx.compose.material.icons.filled.WorkspacePremium
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonColors
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
@@ -57,6 +61,7 @@ import java.time.LocalDate
import java.time.format.DateTimeFormatter
var showNewMarksDialog by mutableStateOf(false)
var showFinalMarksDialog by mutableStateOf(false)
enum class MarksDepthLevel {
All,
@@ -71,8 +76,14 @@ fun MarksScreen() {
MarksDepthLevel.Subject -> MarksSubject()
MarksDepthLevel.Detail -> MarksDetail()
}
NewMarksDialog()
FinalMarksDialog()
}
@Composable
fun NewMarksDialog() {
if (showNewMarksDialog) {
val scrollStateNewMarks = rememberScrollState()
val ss = rememberScrollState()
Dialog(
onDismissRequest = { showNewMarksDialog = false },
@@ -82,7 +93,9 @@ fun MarksScreen() {
)
) {
Column(
Modifier.verticalScroll(scrollStateNewMarks).padding(vertical = 10.dp),
Modifier
.verticalScroll(ss)
.padding(vertical = 10.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
@@ -91,14 +104,17 @@ fun MarksScreen() {
fontWeight = FontWeight.Bold,
fontSize = 30.sp,
textAlign = TextAlign.Center,
modifier = Modifier.background(
modifier = Modifier
.background(
color = Color.Black,
shape = RoundedCornerShape(global.dimens.roundedCorner)
).border(
)
.border(
shape = RoundedCornerShape(global.dimens.roundedCorner),
color = PastelYellow,
width = global.dimens.borderWidth
).padding(10.dp)
)
.padding(10.dp)
)
Spacer(Modifier.height(10.dp))
for ((k, v) in global.newMarks) {
@@ -133,7 +149,8 @@ fun MarksScreen() {
Text(
i.theme,
color = Color.White,
modifier = Modifier.padding(end = 5.dp, top = 5.dp)
modifier = Modifier
.padding(end = 5.dp, top = 5.dp)
.weight(1f)
)
Column(
@@ -146,7 +163,8 @@ fun MarksScreen() {
.background(
color = getAvgColor(i.grade, true),
shape = RoundedCornerShape(global.dimens.roundedCorner)
).padding(5.dp),
)
.padding(5.dp),
style = TextStyle(
shadow = Shadow(
color = Color.Black,
@@ -173,6 +191,47 @@ fun MarksScreen() {
}
}
@Composable
fun FinalMarksDialog() {
if (showFinalMarksDialog) {
val ss = rememberScrollState()
Dialog(
onDismissRequest = { showFinalMarksDialog = false },
properties = DialogProperties(
dismissOnBackPress = true,
dismissOnClickOutside = true
)
) {
Column(
Modifier
.verticalScroll(ss)
.padding(vertical = 10.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
"Uzavřené známky",
color = Color.White,
fontWeight = FontWeight.Bold,
fontSize = 30.sp,
textAlign = TextAlign.Center,
modifier = Modifier
.background(
color = Color.Black,
shape = RoundedCornerShape(global.dimens.roundedCorner)
)
.border(
shape = RoundedCornerShape(global.dimens.roundedCorner),
color = PastelYellow,
width = global.dimens.borderWidth
)
.padding(10.dp)
)
}
}
}
}
private fun getAvgColor(avg: String, isBorder: Boolean = false): Color {
val aux = avg.replace(",", ".").toFloat()
return if (aux in 1f..<1.5f) {
@@ -360,22 +419,47 @@ fun MarksAll() {
}
Box(Modifier.fillMaxSize()) {
Row(
modifier = Modifier.align(Alignment.BottomCenter)
) {
FloatingActionButton(
onClick = { showNewMarksDialog = true },
modifier = Modifier
.align(Alignment.BottomEnd)
// .size(40.dp)
.padding(10.dp)
.background(Color.Black, shape = RoundedCornerShape(global.dimens.roundedCorner)),
containerColor = Color.Black,
contentColor = PastelYellow
.background(
Color.Black,
shape = RoundedCornerShape(global.dimens.roundedCorner)
),
contentColor = PastelYellow,
containerColor = Color.Black
) {
Icon(
modifier = Modifier.padding(start = 4.dp, top = 4.dp),
imageVector = Icons.Default.AutoAwesome,
contentDescription = "New marks in subject",
tint = PastelYellow // You can customize the icon color
)
}
FloatingActionButton(
onClick = { showFinalMarksDialog = true },
modifier = Modifier
// .size(40.dp)
.padding(10.dp)
.background(
Color.Black,
shape = RoundedCornerShape(global.dimens.roundedCorner)
),
contentColor = PastelYellow,
containerColor = Color.Black
) {
Icon(
imageVector = Icons.Default.WorkspacePremium,
contentDescription = "Final marks",
tint = PastelYellow // You can customize the icon color
)
}
}
}
}
@@ -40,7 +40,10 @@ fun MenuScreen() {
Spacer(modifier = Modifier.height(80.dp))
MenuButton({ global.currentScreen = Screen.SignIn }, "Změnit přihlášení")
MenuButton({
global.noSignInBackHandle = false
global.currentScreen = Screen.SignIn
}, "Změnit přihlášení")
Spacer(modifier = Modifier.height(80.dp))
@@ -11,15 +11,21 @@ import org.json.JSONObject
fun setupAPI() {
global.token = "NETWORK_UNREACHABLE"
val token = networkRequestFactory.perform(NetworkRequestType.Token).getString("token")
if (""""error": """ !in token) {
val tokenJSON = networkRequestFactory.perform(NetworkRequestType.Token)
if (tokenJSON.has("token")) {
val token = tokenJSON.getString("token")
if ("\"error\": " !in token) {
global.token = token
}
if (global.token == "NETWORK_UNREACHABLE" || """"error": """ in global.token) {
}
if (global.token == "NETWORK_UNREACHABLE" || "\"error\":" in global.token) {
global.userData = JSONObject()
global.studentId = ""
return
}
global.userData = networkRequestFactory.perform(NetworkRequestType.UserData)
Util.saveStringToFile(global.filePaths.userData, global.userData.toString())
global.studentClass = Parsing.getStudentClass()
@@ -90,7 +96,6 @@ object NetworkRequestFactory: NetworkRequestInterface {
}
private fun getAPI(url: String): JSONObject {
Log.d("debug TOKEN", global.token)
val response = get(url, headersOf(
"Content-Type", "application/x-www-form-urlencoded",
"Authorization", "Bearer ${global.token}"
@@ -153,9 +153,12 @@ class Parsing {
subject.name = subj.getJSONObject("subject").getString("abbrev")
subject.place =
subj.getJSONArray("rooms").getJSONObject(0).getString("abbrev")
subject.teacher = if (subj.getJSONArray("teachers").length() > 0) {
subj.getJSONArray("teachers").getJSONObject(0)
.getString("fullName") // TODO: keep in mind that fullName might not be a valid field (name and surname are!)
subject.teacher =
if (subj.getJSONArray("teachers").length() > 0) {
subj.getJSONArray("teachers")
.getJSONObject(0).getString("name") + " " +
subj.getJSONArray("teachers")
.getJSONObject(0).getString("name")
} else {
""
}
@@ -322,7 +325,6 @@ class Parsing {
timetable.add(day)
}
Log.d("debug", "timetable: $timetable")
return timetable
}
@@ -1,6 +1,7 @@
package com.odweta.solon
import android.content.Context
import android.util.Log
import android.widget.Toast
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.Image
@@ -40,6 +41,7 @@ import androidx.compose.foundation.layout.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
private var buttonText by mutableStateOf("Přihlásit se")
@@ -96,6 +98,7 @@ fun signInButtonCallback(ctx: Context, usernameText: String, passwordText: Strin
global.currentScreen = Screen.Splash
launchStart(ctx)
} else {
withContext(Dispatchers.Main) {
Toast.makeText(
ctx,
"Neplatné přihlašovací údaje nebo nejste připojeni k internetu, zkuste to znovu.",
@@ -104,6 +107,7 @@ fun signInButtonCallback(ctx: Context, usernameText: String, passwordText: Strin
}
}
}
}
@Composable
fun SignInScreen() {
@@ -115,7 +119,6 @@ fun SignInScreen() {
var usernameText by remember { mutableStateOf("") }
var passwordText by remember { mutableStateOf("") }
val ctx = LocalContext.current
val coscope = rememberCoroutineScope()
var isPasswordVisible by remember { mutableStateOf(false) } // State for visibility toggle
val visualTransformation = if (isPasswordVisible) VisualTransformation.None else PasswordVisualTransformation()
@@ -356,6 +356,8 @@ private fun DayScreen(day: Day) {
) {
for ((subjectIndex, subject) in day.subjects.withIndex()) {
val lectureId = Util.getLectureId(day.date, subjectIndex)
global.lectureNotes[lectureId]?.number = subject.number.toInt()
global.lectureNotes[lectureId]?.lectureName = subject.name
val amoledModifier = if (settings.useAmoledMode.checked.value) {
Modifier