6 Commits
10 changed files with 609 additions and 61 deletions
+1 -1
View File
@@ -1,3 +1,3 @@
![solon-logo](./solon_logo.png)
# Zorientujte se rychleji v této odlehčené verzi Školy OnLine
# Odkaz na stažení aplikace pro Android [zde](https://gitlab.com/Odweta/solon/-/raw/master/release/com.odweta.solon_2.2.apk?ref_type=heads&inline=false) (verze 2.2)
# Odkaz na stažení aplikace pro Android [zde](https://gitlab.com/Odweta/solon/-/raw/master/release/com.odweta.solon_2.2.1.apk?ref_type=heads&inline=false) (verze 2.2.1)
+329
View File
@@ -0,0 +1,329 @@
<?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="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>
+2 -2
View File
@@ -12,8 +12,8 @@ android {
applicationId = "com.odweta.solon"
minSdk = 28
targetSdk = 34
versionCode = 205
versionName = "2.2"
versionCode = 206
versionName = "2.2.1"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
@@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
@@ -86,7 +87,9 @@ class Setting(auxId: SettingsId, auxName: String, auxChecked: Boolean) {
enum class SettingsId {
Svoboda,
Amoled,
RefreshButton
RefreshButton,
TagNewMarks,
DeleteLocalData
}
class SettingsData {
@@ -108,7 +111,13 @@ class SettingsData {
true
)
override fun toString() = "$useSvobodaMode\n$useAmoledMode\n$showRefreshButton"
var tagNewMarks: Setting = Setting(
SettingsId.TagNewMarks,
"Označit nové známky",
true
)
override fun toString() = "$useSvobodaMode\n$useAmoledMode\n$showRefreshButton\n$tagNewMarks"
}
var settings : SettingsData = SettingsData()
@@ -138,7 +147,48 @@ var resetNav: Boolean = false
var isAPISetUp: Boolean = false
var lectureNotes: HashMap<Int, MutableState<String>> = hashMapOf()
enum class LectureNoteType {
Normal, // obycejna poznamka
Writing, // pisemny test
Speaking, // ustni zkouseni
Other // cokoliv jineho
}
fun String.toLectureNoteType(): LectureNoteType {
return when(this) {
"Normal" -> LectureNoteType.Normal
"Writing" -> LectureNoteType.Writing
"Speaking" -> LectureNoteType.Speaking
"Other" -> LectureNoteType.Other
else -> LectureNoteType.Normal
}
}
class LectureNote(
id: Int,
note: MutableState<String>,
type: MutableState<LectureNoteType>,
number: MutableState<Int>,
lectureName: MutableState<String>
) {
var id: Int = 0
var note: MutableState<String> =
mutableStateOf("")
var type: MutableState<LectureNoteType> =
mutableStateOf(LectureNoteType.Normal)
var number: MutableState<Int> = mutableIntStateOf(0)
var lectureName: MutableState<String> = mutableStateOf("")
init {
this.id = id
this.note = note
this.type = type
this.number = number
this.lectureName = lectureName
}
}
var lectureNotes: HashMap<Int, MutableState<LectureNote>> = hashMapOf()
var selectedLecture: Int = 0
var selectedDay: Int = 0
@@ -237,7 +237,7 @@ fun MarksAll() {
modifier = Modifier.fillMaxSize().weight(1f),
contentAlignment = Alignment.TopStart
) {
if (subjectContainsNewMark) {
if (subjectContainsNewMark && settings.tagNewMarks.checked.value) {
Icon(
modifier = Modifier.padding(start = 4.dp, top = 4.dp),
imageVector = Icons.Default.AutoAwesome,
@@ -368,7 +368,7 @@ fun MarksSubject() {
},
shape = RoundedCornerShape(roundedCornerDimen)
)
.padding(vertical = 20.dp)
.padding(vertical = 20.dp, horizontal = 10.dp)
) // subject
Spacer(modifier = Modifier.height(20.dp))
@@ -428,7 +428,11 @@ fun MarksSubject() {
}
// only add if mark date is not older than one week
if (LocalDate.parse(mark.date, DateTimeFormatter.ISO_LOCAL_DATE_TIME).isAfter(LocalDate.now().minusWeeks(1))) {
if ((LocalDate
.parse(mark.date, DateTimeFormatter.ISO_LOCAL_DATE_TIME)
.isAfter(LocalDate.now().minusWeeks(1))
) && settings.tagNewMarks.checked.value
) {
Icon(
modifier = Modifier.padding(start = 7.dp, top = 4.dp),
imageVector = Icons.Default.AutoAwesome,
@@ -472,7 +476,7 @@ fun MarksDetail() {
),
modifier = Modifier
.border(
width = 5.dp,
width = borderWidthDimen,
shape = RoundedCornerShape(roundedCornerDimen),
color = PastelYellow
)
@@ -493,9 +497,9 @@ fun MarksDetail() {
.width(70.dp)
.height(70.dp)
.border(
width = 5.dp,
width = borderWidthDimen,
color = getAvgColor(
Util.avg(marks[subjectToShow]!!),
Util.avg(mutableListOf(markToShow)),
true
),
shape = RoundedCornerShape(roundedCornerDimen)
@@ -505,7 +509,7 @@ fun MarksDetail() {
Color.Black
} else {
getAvgColor(
Util.avg(marks[subjectToShow]!!)
Util.avg(mutableListOf(markToShow))
)
}
)
@@ -88,6 +88,10 @@ fun SettingsScreen(modifier: Modifier = Modifier) {
Spacer(Modifier.height(10.dp))
SettingsTableRow(settings.showRefreshButton)
Spacer(Modifier.height(10.dp))
SettingsTableRow(settings.tagNewMarks)
}
}
@@ -117,6 +121,8 @@ fun SettingsTableRow(setting: Setting) {
SettingsId.Svoboda -> settings.useSvobodaMode = setting
SettingsId.Amoled -> settings.useAmoledMode = setting
SettingsId.RefreshButton -> settings.showRefreshButton = setting
SettingsId.TagNewMarks -> settings.tagNewMarks = setting
else -> {}
}
Util.saveStringToFile(settingsDataFilePath, settings.toString())
},
@@ -1,22 +1,21 @@
package com.odweta.solon
import android.annotation.SuppressLint
import android.util.Log
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
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.Image
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState
@@ -24,28 +23,39 @@ import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.selection.TextSelectionColors
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.BasicAlertDialog
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.AutoAwesome
import androidx.compose.material.icons.filled.EditNote
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonColors
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.material3.TextFieldColors
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.focusModifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontStyle
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.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import androidx.compose.ui.window.PopupProperties
import androidx.compose.ui.zIndex
import com.odweta.solon.ui.theme.PastelGreen
import com.odweta.solon.ui.theme.PastelGreenTransparent
@@ -53,11 +63,11 @@ import com.odweta.solon.ui.theme.PastelRed
import com.odweta.solon.ui.theme.PastelRedTransparent
import com.odweta.solon.ui.theme.PastelYellow
import com.odweta.solon.ui.theme.PastelYellowTransparent
import java.security.MessageDigest
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.time.LocalDate
import java.time.LocalTime
import java.time.format.DateTimeFormatter
import kotlin.math.abs
var showDetailDialog = mutableStateOf(false)
@@ -78,7 +88,7 @@ fun TimetableScreen() {
@SuppressLint("UnrememberedMutableState")
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun DetailDialog(modifier: Modifier = Modifier) {
fun DetailDialog() {
Dialog(
onDismissRequest = { showDetailDialog.value = false }, // Close the dialog on dismiss
properties = DialogProperties(
@@ -95,29 +105,131 @@ fun DetailDialog(modifier: Modifier = Modifier) {
shape = RoundedCornerShape(roundedCornerDimen)
)
) {
if (lectureNotes[selectedLecture] == null) {
lectureNotes[selectedLecture] = mutableStateOf("")
}
TextField(
value = lectureNotes[selectedLecture]!!.value,
onValueChange = { newText: String ->
lectureNotes[selectedLecture]!!.value = newText
Util.saveLectureIds()
},
placeholder = { Text("Sem můžete napsat poznámky k\u00A0této hodině.") },
colors = TextFieldDefaults.textFieldColors(
focusedTextColor = Color.White,
containerColor = Color.Black,
selectionColors = TextSelectionColors(
handleColor = PastelYellow,
backgroundColor = PastelYellowTransparent
),
cursorColor = PastelYellow,
focusedIndicatorColor = PastelYellow,
unfocusedIndicatorColor = PastelYellowTransparent
Column(
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = "" +
lectureNotes[selectedLecture]?.value?.number?.value.toString() +
" " +
lectureNotes[selectedLecture]?.value?.lectureName?.value.toString(),
color = Color.White,
textAlign = TextAlign.Left
)
)
///////////////////////////////////////////////////////////
var isExpanded by remember { mutableStateOf(false) }
Button(
modifier = Modifier.background(
color = Color.Black,
shape = RoundedCornerShape(roundedCornerDimen)
),
onClick = { isExpanded = true },
colors = ButtonColors(
containerColor = Color.Black,
contentColor = Color.White,
disabledContainerColor = Color.Black,
disabledContentColor = Color.White
)
) {
val type = when (lectureNotes[selectedLecture]?.value?.type?.value) {
LectureNoteType.Normal -> "Normální"
LectureNoteType.Writing -> "Písemný test"
LectureNoteType.Speaking -> "Ústní zkoušení"
LectureNoteType.Other -> "Jiné"
else -> "Jiné"
}
Text("Typ poznámky: $type")
}
DropdownMenu(
modifier = Modifier.background(color = Color.Black),
onDismissRequest = { isExpanded = false },
expanded = isExpanded,
properties = PopupProperties(
excludeFromSystemGesture = false,
dismissOnClickOutside = true,
dismissOnBackPress = true,
focusable = true
),
) {
DropdownMenuItem(
enabled = true,
onClick = {
isExpanded = false
lectureNotes[selectedLecture]?.value?.type?.value =
LectureNoteType.Normal
},
text = { Text("Normální poznámka", color = Color.White) }
)
DropdownMenuItem(
enabled = true,
onClick = {
isExpanded = false
lectureNotes[selectedLecture]?.value?.type?.value =
LectureNoteType.Writing
},
text = { Text("Písemný test", color = Color.White) }
)
DropdownMenuItem(
enabled = true,
onClick = {
isExpanded = false
lectureNotes[selectedLecture]?.value?.type?.value =
LectureNoteType.Speaking
},
text = { Text("Ústní zkoušení", color = Color.White) }
)
DropdownMenuItem(
enabled = true,
onClick = {
isExpanded = false
lectureNotes[selectedLecture]?.value?.type?.value =
LectureNoteType.Other
},
text = { Text("Jiné", color = Color.White) }
)
}
////////////////////////////////////////////////
if (lectureNotes[selectedLecture] == null) {
lectureNotes[selectedLecture] = mutableStateOf(
LectureNote(
id = 0,
note = mutableStateOf(""),
type = mutableStateOf(LectureNoteType.Normal),
number = mutableIntStateOf(0),
lectureName = mutableStateOf("N/A")
)
)
}
TextField(
value = lectureNotes[selectedLecture]?.value?.note?.value ?: "",
onValueChange = { newText: String ->
lectureNotes[selectedLecture]?.value?.note?.value = newText
Util.saveLectureIds()
},
placeholder = { Text("Sem můžete napsat poznámky k\u00A0této hodině.") }, // &nbsp;
colors = TextFieldDefaults.textFieldColors(
focusedTextColor = Color.White,
containerColor = Color.Black,
selectionColors = TextSelectionColors(
handleColor = PastelYellow,
backgroundColor = PastelYellowTransparent
),
cursorColor = PastelYellow,
focusedIndicatorColor = PastelYellow,
unfocusedIndicatorColor = PastelYellowTransparent
)
)
}
}
}
)
@@ -125,7 +237,7 @@ fun DetailDialog(modifier: Modifier = Modifier) {
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun DayPager(modifier: Modifier = Modifier) {
fun DayPager() {
val pagerState = rememberPagerState(pageCount = { days.size })
HorizontalPager(
state = pagerState,
@@ -218,6 +330,7 @@ fun subjectModifier(d: Day, s: Subject, lectureNumber: Int): Modifier {
}
}
@SuppressLint("UnrememberedMutableState")
@Composable
private fun DayScreen(day: Day) {
val scrollState = rememberScrollState()
@@ -250,6 +363,17 @@ private fun DayScreen(day: Day) {
) {
for ((subjectIndex, subject) in day.subjects.withIndex()) {
val lectureId = Util.getLectureId(day.date, subjectIndex)
if (lectureNotes[lectureId] == null) {
lectureNotes[lectureId] = mutableStateOf(LectureNote(
id = lectureId,
note = mutableStateOf(""),
type = mutableStateOf(LectureNoteType.Normal),
number = mutableIntStateOf(0),
lectureName = mutableStateOf("N/A")
))
}
lectureNotes[lectureId]?.value?.number?.value = subject.number.toInt()
lectureNotes[lectureId]?.value?.lectureName?.value = subject.name
val amoledModifier = if (settings.useAmoledMode.checked.value) {
Modifier
.width(50.dp)
@@ -291,7 +415,10 @@ private fun DayScreen(day: Day) {
}
}
Box (modifier = subjectModifier(day, subject, subject.number.toInt())) {
Box (
modifier = subjectModifier(day, subject, subject.number.toInt()),
contentAlignment = Alignment.TopStart
) {
Row {
if (subject.substitute != "2") {
Box(
@@ -424,7 +551,21 @@ private fun DayScreen(day: Day) {
.clickable {
selectedLecture = lectureId
showDetailDialog.value = true
})
})
if (
lectureNotes[lectureId] == null ||
(lectureNotes[lectureId] != null && lectureNotes[lectureId]?.value?.note?.value != "") ||
(lectureNotes[lectureId] != null && lectureNotes[lectureId]?.value?.type?.value != LectureNoteType.Normal) &&
(lectureNotes[lectureId] != null && lectureNotes[lectureId]?.value?.type?.value != LectureNoteType.Other)
) {
Icon(
modifier = Modifier.padding(start = 3.dp, top = 1.dp),
imageVector = Icons.Default.EditNote,
contentDescription = "Lecture has note",
tint = Color.White // You can customize the icon color
)
}
}
}
}
@@ -9,6 +9,7 @@ import android.os.Build
import android.util.DisplayMetrics
import android.view.WindowManager
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.core.content.pm.PackageInfoCompat
import java.io.File
@@ -268,29 +269,46 @@ class Util {
})
}
fun csvToHashMap(filePath: String): HashMap<Int, MutableState<String>> {
val hashMap = HashMap<Int, MutableState<String>>()
fun csvToHashMap(filePath: String): HashMap<Int, MutableState<LectureNote>> {
val hashMap = HashMap<Int, MutableState<LectureNote>>()
val lines = fileToString(filePath).lines()
for (line in lines) {
if (line.isBlank()) continue
val parts = line.split(",")
if (parts.size == 2) {
val key = parts[0].trim().toInt()
val value = parts[1].trim()
hashMap[key] = mutableStateOf("")
hashMap[key]!!.value = value
if (parts.size == 5) {
val id = parts[0].trim().toInt()
val note = parts[1].trim()
val type = parts[2].trim().toLectureNoteType()
val number = parts[3].trim().toInt()
val lectureName = parts[4].trim()
val lectureNote = LectureNote(
id,
mutableStateOf(note),
mutableStateOf(type),
mutableIntStateOf(number),
mutableStateOf(lectureName)
)
hashMap[id] = mutableStateOf(lectureNote)
}
}
return hashMap
}
fun hashMapToCsv(hashMap: HashMap<Int, MutableState<String>>): String {
fun hashMapToCsv(hashMap: HashMap<Int, MutableState<LectureNote>>): String {
var result = ""
for ((key, value) in hashMap) {
result += "$key,${value.value}\n"
for ((key, lectureNote) in hashMap) {
result +=
"$key," +
"${lectureNote.value.note.value}," +
"${lectureNote.value.type.value}," +
"${lectureNote.value.number.value}," +
lectureNote.value.lectureName.value +
"\n"
}
return result
}
Binary file not shown.
Binary file not shown.