diff --git a/mobile/app/src/main/java/com/odweta/solon/Global.kt b/mobile/app/src/main/java/com/odweta/solon/Global.kt index a3fb5d9..9f3022d 100644 --- a/mobile/app/src/main/java/com/odweta/solon/Global.kt +++ b/mobile/app/src/main/java/com/odweta/solon/Global.kt @@ -3,6 +3,8 @@ package com.odweta.solon import androidx.compose.animation.AnimatedContent import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut +import androidx.compose.animation.slideInHorizontally +import androidx.compose.animation.slideOutHorizontally import androidx.compose.animation.slideInVertically import androidx.compose.animation.slideOutVertically import androidx.compose.animation.togetherWith @@ -14,15 +16,18 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState +import androidx.compose.runtime.RecomposeScope import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp +import androidx.lifecycle.MutableLiveData import com.odweta.solon.ui.theme.PastelYellow import org.json.JSONObject import java.io.File import java.time.LocalDateTime +import java.util.concurrent.Callable enum class Screen { Main, @@ -98,24 +103,6 @@ data class LectureNote( var lectureName: String ) -class LectureNoteOLD(id: Int, note: MutableState, type: MutableState, number: Int, lectureName: String) { - var id: Int = 0 - var note: MutableState = - mutableStateOf("") - var type: MutableState = - mutableStateOf(LectureNoteType.Normal) - var number: Int = 0 - var lectureName: String = "" - - init { - this.id = id - this.note = note - this.type = type - this.number = number - this.lectureName = lectureName - } -} - class Subject { lateinit var name: String lateinit var place: String @@ -288,7 +275,7 @@ var settings = SettingsData() @Composable fun Animate(targetState: T, content: @Composable (target: T) -> Unit) { - if (settings.useAnimations.checked.value) { + if (settings.useAnimations.checked.value == true) { AnimatedContent( targetState = targetState, transitionSpec = { diff --git a/mobile/app/src/main/java/com/odweta/solon/MainActivity.kt b/mobile/app/src/main/java/com/odweta/solon/MainActivity.kt index 49d72a1..b54c0cc 100644 --- a/mobile/app/src/main/java/com/odweta/solon/MainActivity.kt +++ b/mobile/app/src/main/java/com/odweta/solon/MainActivity.kt @@ -8,11 +8,20 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.size +import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.currentRecomposeScope +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.toArgb +import androidx.compose.ui.input.pointer.PointerIcon.Companion.Text +import androidx.compose.ui.unit.dp import com.odweta.solon.ui.theme.SolonTheme class MainActivity : ComponentActivity() { diff --git a/mobile/app/src/main/java/com/odweta/solon/Marks.kt b/mobile/app/src/main/java/com/odweta/solon/Marks.kt index 5fb25b0..32c9b5a 100644 --- a/mobile/app/src/main/java/com/odweta/solon/Marks.kt +++ b/mobile/app/src/main/java/com/odweta/solon/Marks.kt @@ -302,7 +302,7 @@ fun MarksAll() { .verticalScroll(scrollState) ) { for ((subject, markList) in global.marks) { - val amoledModifier = if (settings.useAmoledMode.checked.value) { + val amoledModifier = if (settings.useAmoledMode.checked.value == true) { Modifier .width(150.dp) .fillMaxHeight() @@ -324,7 +324,7 @@ fun MarksAll() { ) } - val amoledModifierBackground = if (settings.useAmoledMode.checked.value) { + val amoledModifierBackground = if (settings.useAmoledMode.checked.value == true) { Modifier .fillMaxWidth() .height(70.dp) @@ -354,7 +354,7 @@ fun MarksAll() { } } - val amoledSpacerModifier = if (settings.useAmoledMode.checked.value) { + val amoledSpacerModifier = if (settings.useAmoledMode.checked.value == true) { Modifier .width(10.dp) .fillMaxHeight() @@ -518,7 +518,7 @@ fun MarksSubject() { shape = RoundedCornerShape(global.dimens.roundedCorner) ) .background( - color = if (settings.useAmoledMode.checked.value) { + color = if (settings.useAmoledMode.checked.value == true) { Color.Black } else { getAvgColor( @@ -559,7 +559,7 @@ fun MarksSubject() { shape = RoundedCornerShape(global.dimens.roundedCorner) ) .background( - color = if (settings.useAmoledMode.checked.value) { + color = if (settings.useAmoledMode.checked.value == true) { Color.Black } else { PastelYellowTransparent @@ -586,7 +586,7 @@ fun MarksSubject() { .fillMaxWidth() .padding(horizontal = 5.dp) .background( - color = if (settings.useAmoledMode.checked.value) { + color = if (settings.useAmoledMode.checked.value == true) { Color.Black } else { getAvgColor(mark.grade) @@ -666,7 +666,7 @@ fun MarksDetail() { shape = RoundedCornerShape(global.dimens.roundedCorner) ) .background( - if (settings.useAmoledMode.checked.value) { + if (settings.useAmoledMode.checked.value == true) { Color.Black } else { getAvgColor( @@ -702,7 +702,7 @@ fun MarksDetail() { shape = RoundedCornerShape(global.dimens.roundedCorner) ) .background( - if (settings.useAmoledMode.checked.value) { + if (settings.useAmoledMode.checked.value == true) { Color.Black } else { PastelYellowTransparent @@ -719,7 +719,7 @@ fun MarksDetail() { .fillMaxWidth() .padding(horizontal = 5.dp) .background( - color = if (settings.useAmoledMode.checked.value) { + color = if (settings.useAmoledMode.checked.value == true) { Color.Black } else { PastelYellowTransparent @@ -762,7 +762,7 @@ fun MarksDetail() { .fillMaxWidth() .padding(horizontal = 5.dp) .background( - color = if (settings.useAmoledMode.checked.value) { + color = if (settings.useAmoledMode.checked.value == true) { Color.Black } else { PastelYellowTransparent diff --git a/mobile/app/src/main/java/com/odweta/solon/Navbar.kt b/mobile/app/src/main/java/com/odweta/solon/Navbar.kt index 81eaa33..62704d9 100644 --- a/mobile/app/src/main/java/com/odweta/solon/Navbar.kt +++ b/mobile/app/src/main/java/com/odweta/solon/Navbar.kt @@ -38,7 +38,7 @@ fun NavbarScreen() { verticalAlignment = Alignment.CenterVertically ) { var spacerModifier = 30.dp - if (settings.showRefreshButton.checked.value) { + if (settings.showRefreshButton.checked.value == true) { spacerModifier = 15.dp Button( onClick = { diff --git a/mobile/app/src/main/java/com/odweta/solon/Settings.kt b/mobile/app/src/main/java/com/odweta/solon/Settings.kt index 4f5aecd..0adffd2 100644 --- a/mobile/app/src/main/java/com/odweta/solon/Settings.kt +++ b/mobile/app/src/main/java/com/odweta/solon/Settings.kt @@ -18,13 +18,22 @@ import androidx.compose.material3.SwitchColors import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.currentComposer +import androidx.compose.runtime.currentRecomposeScope +import androidx.compose.runtime.getValue +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.graphics.Color import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.lifecycle.liveData import com.odweta.solon.ui.theme.PastelYellow +import kotlinx.coroutines.launch @Composable fun SettingsScreen() { @@ -75,15 +84,9 @@ fun SettingsTableRow(setting: Setting) { Spacer(modifier = Modifier.weight(1f)) Switch( - checked = setting.checked.value, + checked = setting.checked.value == true, onCheckedChange = { setting.checked.value = it - when (setting.id) { - SettingsId.Svoboda -> settings.useSvobodaMode = setting - SettingsId.Amoled -> settings.useAmoledMode = setting - SettingsId.RefreshButton -> settings.showRefreshButton = setting - SettingsId.Animations -> settings.useAnimations = setting - } Util.saveStringToFile(global.filePaths.settings, settings.toString()) }, colors = SwitchColors( diff --git a/mobile/app/src/main/java/com/odweta/solon/Timetable.kt b/mobile/app/src/main/java/com/odweta/solon/Timetable.kt index 0357015..c972654 100644 --- a/mobile/app/src/main/java/com/odweta/solon/Timetable.kt +++ b/mobile/app/src/main/java/com/odweta/solon/Timetable.kt @@ -293,7 +293,7 @@ fun subjectModifier(d: Day, s: Subject, lectureNumber: Int): Modifier { global.currentLectureNumber = lectureNumber } - val m = if (settings.useAmoledMode.checked.value) { + val m = if (settings.useAmoledMode.checked.value == true) { Modifier .fillMaxWidth() .height(70.dp) @@ -359,7 +359,7 @@ private fun DayScreen(day: Day) { global.lectureNotes[lectureId]?.number = subject.number.toInt() global.lectureNotes[lectureId]?.lectureName = subject.name - val amoledModifier = if (settings.useAmoledMode.checked.value) { + val amoledModifier = if (settings.useAmoledMode.checked.value == true) { Modifier .width(50.dp) .fillMaxHeight() @@ -484,7 +484,7 @@ private fun DayScreen(day: Day) { .padding(vertical = 5.dp), contentAlignment = Alignment.Center ) { - if (settings.useSvobodaMode.checked.value) { + if (settings.useSvobodaMode.checked.value == true) { if ( subject.teacher == "Jindřich Svoboda" && global.studentClass == "5. G" diff --git a/mobile/app/src/main/java/com/odweta/solon/Toolbar.kt b/mobile/app/src/main/java/com/odweta/solon/Toolbar.kt index e0bdc7e..6f9464e 100644 --- a/mobile/app/src/main/java/com/odweta/solon/Toolbar.kt +++ b/mobile/app/src/main/java/com/odweta/solon/Toolbar.kt @@ -1,10 +1,21 @@ package com.odweta.solon +import android.content.Context import android.util.Log +import android.widget.ImageView +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.slideInHorizontally +import androidx.compose.animation.slideOutHorizontally +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Upload +import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect @@ -12,16 +23,22 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.setValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.compose.ui.viewinterop.AndroidView +import com.bumptech.glide.Glide import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.launch import org.json.JSONObject +private var showLoadingIcon by mutableStateOf(false) + @Composable fun ToolbarScreen() { // make the font size adaptive relative to the length of the user's name @@ -43,12 +60,28 @@ fun ToolbarScreen() { toolbarTextSizeAdaptive = 10.sp } - Box(modifier = Modifier.padding(10.dp)) { - Text( - text = global.status, - fontSize = toolbarTextSizeAdaptive, - color = Color.White - ) + Animate(global.status) { targetText -> + Row(modifier = Modifier.padding(10.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Center) { + Text( + text = targetText, + fontSize = toolbarTextSizeAdaptive, + color = Color.White + ) + + if (settings.useAnimations.checked.value == true) { + AnimatedVisibility(showLoadingIcon) { + AndroidView( + modifier = Modifier.size(50.dp).padding(start = 10.dp), + factory = { context: Context -> ImageView(context) }, + update = { imageView -> + Glide.with(imageView.context) + .load(R.drawable.loading) + .into(imageView) + } + ) + } + } + } } } @@ -80,20 +113,14 @@ object StatusFactory: StatusFactoryInterface { StatusType.Loading -> { CoroutineScope(Dispatchers.IO).launch { global.refreshed = false - val anim = listOf( - "Načítání nových dat", - "Načítání nových dat.", - "Načítání nových dat..", - "Načítání nových dat...", - "Načítání nových dat..", - "Načítání nových dat." - ) - var i = 0 + showStatus("Načítání nových dat") + delay(100L) + showLoadingIcon = true + while (!global.refreshed) { - if (i == anim.size) i = 0 - showStatus(anim[i++]) - delay(300) + showStatus("Načítání nových dat") } + showLoadingIcon = false } } }