added animations, changed signOut screen

This commit is contained in:
Odweta
2024-12-31 17:22:09 +01:00
parent 1516a00841
commit 81fb398ae2
6 changed files with 207 additions and 88 deletions
@@ -1,10 +1,18 @@
package com.odweta.solon
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.animation.togetherWith
import androidx.compose.foundation.border
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.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
@@ -34,7 +42,8 @@ class Setting(auxId: SettingsId, auxName: String, auxChecked: Boolean) {
enum class SettingsId {
Svoboda,
Amoled,
RefreshButton
RefreshButton,
Animations
}
class SettingsData {
@@ -56,7 +65,13 @@ class SettingsData {
true
)
override fun toString() = "$useSvobodaMode\n$useAmoledMode\n$showRefreshButton"
var useAnimations: Setting = Setting(
SettingsId.Animations,
"Používat animace v aplikaci",
true
)
override fun toString() = "$useSvobodaMode\n$useAmoledMode\n$showRefreshButton\n$useAnimations"
}
enum class LectureNoteType {
@@ -184,7 +199,8 @@ enum class ScreenElement {
Marks,
Menu,
About,
Settings
Settings,
SignOut
}
class Global {
@@ -268,3 +284,22 @@ class Global {
val global = Global()
var settings = SettingsData()
@Composable
fun <T> Animate(targetState: T, content: @Composable (target: T) -> Unit) {
if (settings.useAnimations.checked.value) {
AnimatedContent(
targetState = targetState,
transitionSpec = {
(slideInVertically(initialOffsetY = { it }) + fadeIn()).togetherWith(
slideOutVertically(targetOffsetY = { it }) + fadeOut()
)
},
modifier = Modifier.fillMaxSize(), label = "animated content"
) { target ->
content(target)
}
} else {
content(targetState)
}
}
@@ -28,10 +28,17 @@ fun remoteLoad(ctx: Context) {
if (!global.isAPISetUp) {
CoroutineScope(Dispatchers.IO)
.launch {
// setup API
setupAPI()
// fetch remote data
global.timetableJSON = networkRequestFactory.perform(NetworkRequestType.Timetable)
global.marksJSON = networkRequestFactory.perform(NetworkRequestType.Marks)
// save to local for later local load
Util.saveStringToFile(global.filePaths.timetable, global.timetableJSON.toString())
Util.saveStringToFile(global.filePaths.marks, global.marksJSON.toString())
launchContinue(
ctx,
global.timetableJSON,
@@ -76,9 +83,8 @@ fun launchContinue(
global.marks = parsedMarks
global.newMarks = Parsing.parseNewMarks(marks)
// load the settings
val settingsData = Util.fileToString(global.filePaths.settings).toSettingsData()
global.settings = settingsData
// // load the settings
// global.settings = Util.fileToString(global.filePaths.settings).toSettingsData()
// load the lecture notes
Util.loadLectureNotes()
@@ -3,6 +3,16 @@ package com.odweta.solon
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.animation.SizeTransform
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.animation.togetherWith
import androidx.compose.animation.with
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
@@ -19,17 +29,22 @@ class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// for seemless <currentScreen> switching
window.statusBarColor = Color.Black.toArgb()
window.setBackgroundDrawable(resources.getDrawable(R.drawable.black))
global.fileDir = applicationContext.filesDir
launchStart(applicationContext)
setContent {
SolonTheme {
when (global.currentScreen) {
Screen.Main -> if (global.launched) MainScreen()
Screen.Splash -> SplashScreen()
Screen.SignIn -> SignInScreen()
Animate(global.currentScreen) { targetScreen ->
when (targetScreen) {
Screen.Main -> if (global.launched) MainScreen()
Screen.Splash -> SplashScreen()
Screen.SignIn -> SignInScreen()
}
}
}
}
@@ -54,12 +69,15 @@ class MainActivity : ComponentActivity() {
.fillMaxWidth()
.weight(1f)
) {
when (global.currentScreenElement) {
ScreenElement.Timetable -> TimetableScreen()
ScreenElement.Marks -> MarksScreen()
ScreenElement.Menu -> MenuScreen()
ScreenElement.About -> AboutScreen()
ScreenElement.Settings -> SettingsScreen()
Animate(global.currentScreenElement) { targetScreen ->
when (targetScreen) {
ScreenElement.Timetable -> TimetableScreen()
ScreenElement.Marks -> MarksScreen()
ScreenElement.Menu -> MenuScreen()
ScreenElement.About -> AboutScreen()
ScreenElement.Settings -> SettingsScreen()
ScreenElement.SignOut -> SignOutScreen()
}
}
}
@@ -1,5 +1,12 @@
package com.odweta.solon
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.scaleIn
import androidx.compose.animation.scaleOut
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
@@ -36,7 +43,7 @@ fun MenuScreen() {
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
MenuButton({ showDialog = true }, "Odhlásit se")
MenuButton({ global.currentScreenElement = ScreenElement.SignOut }, "Odhlásit se")
Spacer(modifier = Modifier.height(80.dp))
@@ -53,69 +60,6 @@ fun MenuScreen() {
MenuButton({ global.currentScreenElement = ScreenElement.Settings }, "Nastavení")
}
// Dialog implementation
if (showDialog) {
AlertDialog(
onDismissRequest = { showDialog = false }, // Close the dialog on dismiss
title = {
Text(text = "Odhlásit se", color = Color.White)
},
text = {
Text("Opravdu se chcete odhlásit? Tato akce zavře aplikaci.", color = Color.White)
},
containerColor = Color.Black,
modifier = Modifier
.border(
width = global.dimens.borderWidth,
color = PastelYellow,
shape = RoundedCornerShape(global.dimens.roundedCorner)), // Yellow border
confirmButton = {
Button(
onClick = {
showDialog = false
Util.deleteFile(global.filePaths.userData)
Util.deleteFile(global.filePaths.timetable)
Util.deleteFile(global.filePaths.marks)
Util.deleteFile(global.filePaths.accountData)
Util.deleteFile(global.filePaths.lectureNotes)
// do not delete settings
exitProcess(0)
},
colors = ButtonDefaults.buttonColors(
containerColor = Color.Black, // Black background for the button
contentColor = Color.White // Yellow text for the button
),
modifier = Modifier
.border(
width = global.dimens.borderWidth,
color = PastelYellow,
shape = RoundedCornerShape(global.dimens.roundedCorner)) // Yellow border
) {
Text("Ano")
}
},
dismissButton = {
Button(
onClick = {
showDialog = false
},
colors = ButtonDefaults.buttonColors(
containerColor = Color.Black, // Black background for the button
contentColor = Color.White,
// Yellow text for the button
),
modifier = Modifier
.border(
width = global.dimens.borderWidth,
color = PastelYellow,
shape = RoundedCornerShape(global.dimens.roundedCorner)) // Yellow border
) {
Text("Ne")
}
}
)
}
}
@Composable
@@ -1,5 +1,6 @@
package com.odweta.solon
import android.util.Log
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
@@ -16,6 +17,7 @@ import androidx.compose.material3.Switch
import androidx.compose.material3.SwitchColors
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
@@ -29,6 +31,10 @@ fun SettingsScreen() {
// handle the back gesture (back swipe form side or back button on bottom android navbar)
BackHandler { global.currentScreenElement = ScreenElement.Menu }
// load the settings dat every time the settings screen is opened,
// maybe i can add a flag that determines if the settings are up to date?
settings = Util.fileToString(global.filePaths.settings).toSettingsData()
val scrollState = rememberScrollState()
Column(modifier = Modifier
@@ -38,22 +44,20 @@ fun SettingsScreen() {
) {
backButtonFactory.get(BackButtonType.Menu)()
Spacer(Modifier.height(10.dp))
SettingsTableRow(settings.useSvobodaMode)
Spacer(Modifier.height(10.dp))
SettingsTableRow(settings.useAmoledMode)
Spacer(Modifier.height(10.dp))
SettingsTableRow(settings.showRefreshButton)
SettingsTableRow(settings.useAnimations)
}
}
@Composable
fun SettingsTableRow(setting: Setting) {
Spacer(Modifier.height(10.dp))
Row(
modifier = Modifier
.padding(10.dp)
@@ -78,7 +82,7 @@ fun SettingsTableRow(setting: Setting) {
SettingsId.Svoboda -> settings.useSvobodaMode = setting
SettingsId.Amoled -> settings.useAmoledMode = setting
SettingsId.RefreshButton -> settings.showRefreshButton = setting
else -> {}
SettingsId.Animations -> settings.useAnimations = setting
}
Util.saveStringToFile(global.filePaths.settings, settings.toString())
},
@@ -113,6 +117,7 @@ fun String.toSettingsData(): SettingsData {
val useSvobodaMode = settings[0].split("#")
val useAmoledMode = settings[1].split("#")
val showRefreshButton = settings[2].split("#")
val useAnimations = settings[3].split("#")
auxSettingsData.useSvobodaMode.id = SettingsId.Svoboda
auxSettingsData.useSvobodaMode.name = useSvobodaMode[1]
@@ -126,5 +131,9 @@ fun String.toSettingsData(): SettingsData {
auxSettingsData.showRefreshButton.name = showRefreshButton[1]
auxSettingsData.showRefreshButton.checked.value = showRefreshButton[2].toBoolean()
auxSettingsData.useAnimations.id = SettingsId.Animations
auxSettingsData.useAnimations.name = useAnimations[1]
auxSettingsData.useAnimations.checked.value = useAnimations[2].toBoolean()
return auxSettingsData
}
@@ -0,0 +1,107 @@
package com.odweta.solon
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.Image
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
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.style.TextAlign
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.TextUnitType
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.odweta.solon.ui.theme.PastelYellow
import kotlin.system.exitProcess
@Composable
fun SignOutScreen() {
// handle the back gesture (back swipe form side or back button on bottom android navbar)
BackHandler { global.currentScreenElement = ScreenElement.Menu }
Column(
modifier = Modifier
.fillMaxSize(),
verticalArrangement = Arrangement.Top,
horizontalAlignment = Alignment.Start
) {
backButtonFactory.get(BackButtonType.Menu)()
Column(
modifier = Modifier
.fillMaxWidth()
.weight(1f),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = "Opravdu se chcete odhlásit? Tato akce zavře aplikaci.",
color = Color.White,
textAlign = TextAlign.Center,
fontSize = 27.sp,
lineHeight = 40.sp,
modifier = Modifier.padding(bottom = 10.dp)
)
Row {
SignOutButton(
onClick = {
Util.deleteFile(global.filePaths.userData)
Util.deleteFile(global.filePaths.timetable)
Util.deleteFile(global.filePaths.marks)
Util.deleteFile(global.filePaths.accountData)
Util.deleteFile(global.filePaths.lectureNotes)
// do not delete settings
exitProcess(0)
},
label = "Ano"
)
Spacer(Modifier.width(10.dp))
SignOutButton(
onClick = {
global.currentScreenElement = ScreenElement.Menu
},
label = "Ne"
)
}
}
}
}
@Composable
private fun SignOutButton(onClick: () -> Unit, label: String) {
Button(
onClick = onClick,
colors = ButtonDefaults.buttonColors(
containerColor = Color.Black, // Black background for the button
contentColor = Color.White // Yellow text for the button
),
modifier = Modifier
.border(
width = global.dimens.borderWidth,
color = PastelYellow,
shape = RoundedCornerShape(global.dimens.roundedCorner)
) // Yellow border
) {
Text(label)
}
}