added animations, changed signOut screen
This commit is contained in:
@@ -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,14 +29,18 @@ 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) {
|
||||
Animate(global.currentScreen) { targetScreen ->
|
||||
when (targetScreen) {
|
||||
Screen.Main -> if (global.launched) MainScreen()
|
||||
Screen.Splash -> SplashScreen()
|
||||
Screen.SignIn -> SignInScreen()
|
||||
@@ -34,6 +48,7 @@ class MainActivity : ComponentActivity() {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun MainScreen() {
|
||||
@@ -54,12 +69,15 @@ class MainActivity : ComponentActivity() {
|
||||
.fillMaxWidth()
|
||||
.weight(1f)
|
||||
) {
|
||||
when (global.currentScreenElement) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user