Stundenplan most definitely finished

Added Commenting to StundenplanActivity and TimeTableSetupActivity
This commit is contained in:
matthias
2024-06-07 02:13:02 +02:00
parent f091451fe8
commit 30ad4bed64
2 changed files with 414 additions and 178 deletions

View File

@@ -2,17 +2,23 @@ package com.schoolapp.cleverclass
import android.content.Context
import android.content.Intent
import android.graphics.drawable.Icon
import android.icu.text.DecimalFormat
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.defaultMinSize
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.wrapContentWidth
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.outlined.Edit
@@ -25,15 +31,9 @@ import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
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.platform.LocalContext
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.unit.dp
import androidx.core.content.ContextCompat.startActivity
import com.schoolapp.cleverclass.LessonStoreManager.getLessons
@@ -43,7 +43,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
private val listOfDays = listOf("Mo", "Di", "Mi", "Do", "Fr")
private val lessonGrabberIndex = 0
private val listOfBreakIndexes = mutableListOf<Int>()
class StundenplanActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
@@ -52,12 +52,26 @@ class StundenplanActivity : ComponentActivity() {
val sharedPreferences = this.getSharedPreferences("TimeTable", Context.MODE_PRIVATE)
val setupDone = sharedPreferences.getBoolean("setupDone", false)
val lessons = MutableList(5) { listOf<LessonData>() }
//Loading saved lessons when NOT auto-loading the setup
if (setupDone) {
listOfDays.forEachIndexed() { index, dayLessons ->
CoroutineScope(Dispatchers.IO).launch {
getLessons(this@StundenplanActivity, dayLessons).collect { savedLessons ->
lessons[index] = savedLessons.toMutableList()
}
}
}
}
setContent {
CleverClassTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
//Auto-load setup, if incomplete
if (!setupDone) {
val intent = Intent(this@StundenplanActivity, TimeTableSetupActivity::class.java).apply {
putExtra(TimeTableSetupActivity.TYPE_KEY, "TimeSetup")
@@ -65,7 +79,7 @@ class StundenplanActivity : ComponentActivity() {
startActivity(intent)
}
StundenplanContent(activity = this)
StundenplanContent(activity = this, lessons)
}
}
}
@@ -75,7 +89,19 @@ class StundenplanActivity : ComponentActivity() {
// Content of Stundenplan
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun StundenplanContent(activity: ComponentActivity){
fun StundenplanContent(activity: ComponentActivity, loadedLessons: List<List<LessonData>>){
//Declaration of most sharedPreferences-stored data (same SharedPreferences as in TimeTableSetupActivity.kt)
val sharedPreferences = activity.getSharedPreferences("TimeTable", Context.MODE_PRIVATE)
val lessonLength = sharedPreferences.getInt("lessonLength", 0)
val firstLesson = sharedPreferences.getFloat("firstLesson", 0.0f).toString()
val breakAmnt = sharedPreferences.getInt("breakAmnt", 0)
val listOfBreakStartTimes = mutableListOf<String>()
val listOfBreakLengths = mutableListOf<Int>()
for (i in 0 until breakAmnt) {
listOfBreakStartTimes.add(sharedPreferences.getFloat("break${i}StartTime", 0.0f).toString())
listOfBreakLengths.add(sharedPreferences.getInt("break${i}Length", 0))
}
Column() {
TopAppBar(
colors = TopAppBarDefaults.centerAlignedTopAppBarColors(MaterialTheme.colorScheme.primaryContainer),
@@ -95,8 +121,10 @@ fun StundenplanContent(activity: ComponentActivity){
}
},
actions ={
IconButton(onClick = {
val intent = Intent(activity, TimeTableSetupActivity::class.java).apply {
//Edit button
IconButton(
onClick = {
val intent = Intent(activity, TimeTableSetupActivity::class.java).apply {
putExtra(TimeTableSetupActivity.TYPE_KEY, "TimeSetup")
}
startActivity(activity, intent, null)
@@ -112,48 +140,235 @@ fun StundenplanContent(activity: ComponentActivity){
modifier = Modifier.fillMaxWidth()
)
Column() {
listOfDays.forEach() {currentDay ->
Day(currentDay)
//Start of the timetable --> One Row() with multiple Column() to create the table
Row(
modifier = Modifier
.verticalScroll(rememberScrollState())
.horizontalScroll(rememberScrollState())
) {
//Left-handed lesson indexing with beginning time of each lesson or break
InfoColumn(
loadedLessons = loadedLessons,
breakAmnt = breakAmnt,
breaksStartTime = listOfBreakStartTimes,
firstLesson = firstLesson,
lessonLength = lessonLength,
breaksLength = listOfBreakLengths
)
//Creation of 5 Columns
loadedLessons.forEachIndexed() { index, dailyLessons ->
Column(modifier = Modifier.wrapContentWidth()) {
//Additional extraIndex to count lessons without breaks getting into the way
var extraIndex = 0
//Box with the day on top of each Column()
Box(
modifier = Modifier
.size(200.dp, 50.dp)
.padding(3.dp)
.border(
width = 1.dp,
color = MaterialTheme.colorScheme.primaryContainer
)
) {
Text(
text = listOfDays[index],
modifier = Modifier.align(Alignment.Center),
style = MaterialTheme.typography.labelMedium
)
}
//Core timetable
//One Box for each lesson or break
for (i in 0 until (dailyLessons.size + breakAmnt)) {
//If the current index is saved as a break in listOfBreakIndexes --> Spacer Box
if (listOfBreakIndexes.indexOf(i) != -1) {
Box(
modifier = Modifier
.size(200.dp, 100.dp)
.padding(3.dp)
)
}
//Else creation of a Box containing all the information from the LessonData object
else if (dailyLessons != emptyList<LessonData>()) {
LessonBox(subject = dailyLessons[extraIndex].subject, teacher = dailyLessons[extraIndex].teacher, room = dailyLessons[extraIndex].room)
//ExtraIndex counted up only here as it does only index the lessons and NOT the breaks
extraIndex++
}
}
}
}
//Right-handed lesson indexing with beginning time of each lesson or break
InfoColumn(
loadedLessons = loadedLessons,
breakAmnt = breakAmnt,
breaksStartTime = listOfBreakStartTimes,
firstLesson = firstLesson,
lessonLength = lessonLength,
breaksLength = listOfBreakLengths
)
}
}
}
//Data class to save objects via DataShare containing information about lessons
data class LessonData(
var subject: String,
var teacher: String,
var room: String
)
@Composable
fun Day(day: String) {
var lessons = emptyList<LessonData>()
val context = LocalContext.current
Column {
LaunchedEffect(lessons, context) {
getLessons(context, day).collect { savedLessons ->
lessons = savedLessons.toMutableList()
}
}
lessons.forEach() {lessonData ->
Lesson(subject = lessonData.subject, teacher = lessonData.teacher, room = lessonData.room)
}
}
}
//Implementation of Box with a darker border than the other Boxes
// contains the information from the corresponding LessonData object
@Composable
fun Lesson(subject: String, teacher: String, room: String) {
fun LessonBox(subject: String, teacher: String, room: String) {
Box(modifier = Modifier
.size(200.dp, 100.dp)
.defaultMinSize(200.dp, 100.dp)
.padding(3.dp)
.border(
width = 1.dp,
color = MaterialTheme.colorScheme.onPrimaryContainer
)
) {
Text(
modifier = Modifier.align(Alignment.Center),
text = "$subject\n@$room\n/w$teacher")
text = "$subject\n@$room\n/w$teacher",
style = MaterialTheme.typography.labelMedium
)
}
}
fun currentDay(): String {
return "hi"
//Left-/Right-Handed info Column
@Composable
fun InfoColumn(loadedLessons: List<List<LessonData>>, breakAmnt: Int, breaksStartTime: List<String>, firstLesson: String, lessonLength: Int, breaksLength: List<Int>) {
Column {
//Determining how much lessons the longest day of the week has
var maxLessons = 0
for (dailyLessons in loadedLessons) {
if (dailyLessons.size > maxLessons) {
maxLessons = dailyLessons.size
}
}
//Variable for time management with custom break times
var lessonTimeIncrement = 0
//Variable for decreasing the number in the InfoColumn after a "Pause" String
var lessonNegIncrement = 0
//Additional extraIndex to count lessons without breaks getting into the way
var extraIndex = 0
//Clear the list of brake indexes needed earlier in the timetable core
listOfBreakIndexes.drop(listOfBreakIndexes.size)
//Spacer Box
Box(
modifier = Modifier
.size(100.dp, 50.dp)
.padding(3.dp)
)
//Loop for creating Boxes on the side
for (i in 0 until (maxLessons + breakAmnt)) {
//Boolean to avoid double creation of the same Box
var loopDone = false
//Loop through all saved break start time
for (breakTime in breaksStartTime) {
if (!loopDone) {
//Variable = minutes of the currently looked at break
var formattedBreakSubstring = breakTime.substringAfter('.')
//When the Float wos like XX.n, it the n-Part will be n0 (fix for values 10, 20, etc.)
if (formattedBreakSubstring == "1" || formattedBreakSubstring == "2" || formattedBreakSubstring == "3" || formattedBreakSubstring == "4" || formattedBreakSubstring == "5") {
formattedBreakSubstring += "0"
}
//Format start time of the break the same way as the lesson start time is formatted
val formattedBreakTime = "@" + DecimalFormat("00").format(breakTime.substringBefore('.').toInt()) + ":" + DecimalFormat("00").format(formattedBreakSubstring.toInt())
//Check whether the start time of the currently looked at brake and lesson are the sa,e
if (substringHelper(extraIndex, firstLesson, lessonLength, lessonTimeIncrement) == formattedBreakTime) {
Box(
modifier = Modifier
.size(100.dp)
.padding(3.dp)
.border(
width = 1.dp,
color = MaterialTheme.colorScheme.primaryContainer
)
) {
//"Pause" String instead of indexing
Text(
modifier = Modifier.align(Alignment.Center),
text = "Pause",
textDecoration = TextDecoration.Underline,
style = MaterialTheme.typography.labelLarge
)
//String with the starting time of the current break
Text(
modifier = Modifier
.align(Alignment.BottomCenter)
.padding(3.dp),
text = formattedBreakTime,
style = MaterialTheme.typography.labelMedium
)
//Add length of current break to the increment
lessonTimeIncrement += breaksLength[breaksStartTime.indexOf(breakTime)]
//Add info that one moe brake exists to the indexing increment
lessonNegIncrement++
//Add the extraIndex (overallIndex) into the listOfBreakIndexes list to include breaks in timetable core
listOfBreakIndexes.add(extraIndex)
//Prevent double creation of Boxes
loopDone = true
}
}
//When looped through all breaks, but none fitted
else if (breakTime == breaksStartTime.last()) {
Box(
modifier = Modifier
.size(100.dp)
.padding(3.dp)
.border(
width = 1.dp,
color = MaterialTheme.colorScheme.primaryContainer
)
) {
//String with the indexing of the lessons
Text(
modifier = Modifier.align(Alignment.Center),
text = "${i + 1 - lessonNegIncrement}:",
textDecoration = TextDecoration.Underline,
style = MaterialTheme.typography.labelLarge
)
//String with the starting time of the lesson
Text(
modifier = Modifier
.align(Alignment.BottomCenter)
.padding(3.dp),
text = substringHelper(extraIndex, firstLesson, lessonLength, lessonTimeIncrement),
style = MaterialTheme.typography.labelMedium
)
//Prevent double creation of Boxes
loopDone = true
//Counting up the lesson only index
extraIndex++
}
}
}
}
}
}
}
//Function that moves the formatting and calculation of the lesson start times away from in-line
fun substringHelper (int: Int, eductString: String, lessonLength: Int, increment: Int): String {
//Variable = minutes of the entered Time
var subString = eductString.substringAfter('.')
//Fix of 10, 20, etc.
if (subString == "1" || subString == "2" || subString == "3" || subString == "4" || subString == "5") {
subString += "0"
}
//Calculation based on start time of the first hour, lesson length, indexing of the current lesson (extraIndex!) and the increment calculated from the break times
//Formatting to "@hh:mm"
val productString = "@" + DecimalFormat("00").format((((subString.toInt() + int * lessonLength) + increment) / 60) + eductString.substringBefore('.').toInt()) + ":" + DecimalFormat("00").format((((subString.toInt()) + int * lessonLength) + increment) % 60)
//Return statement to use the formatted and calculated product in the timetable
return productString
}

View File

@@ -22,6 +22,7 @@ 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.text.KeyboardOptions
@@ -29,21 +30,30 @@ import androidx.compose.foundation.text.selection.TextSelectionColors
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.outlined.Delete
import androidx.compose.material.icons.outlined.Edit
import androidx.compose.material.icons.outlined.Info
import androidx.compose.material.ripple.LocalRippleTheme
import androidx.compose.material.ripple.RippleAlpha
import androidx.compose.material.ripple.RippleTheme
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button
import androidx.compose.material3.Checkbox
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.FilledTonalButton
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Surface
import androidx.compose.material3.Tab
import androidx.compose.material3.TabRow
import androidx.compose.material3.Text
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
@@ -53,32 +63,22 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import com.schoolapp.cleverclass.ui.theme.CleverClassTheme
import com.schoolapp.cleverclass.ui.theme.InputPrimaryColor
import com.schoolapp.cleverclass.ui.theme.InputSecondaryColor
import androidx.compose.foundation.layout.width
import androidx.compose.material.icons.outlined.Edit
import androidx.compose.material.ripple.LocalRippleTheme
import androidx.compose.material.ripple.RippleAlpha
import androidx.compose.material.ripple.RippleTheme
import androidx.compose.material3.FilledTonalButton
import androidx.compose.material3.OutlinedButton
import java.util.Locale
import androidx.compose.material3.Checkbox
import androidx.compose.material3.Tab
import androidx.compose.material3.TabRow
import androidx.compose.runtime.CompositionLocalProvider
import androidx.core.content.ContextCompat.startActivity
import com.schoolapp.cleverclass.LessonStoreManager.getLessons
import com.schoolapp.cleverclass.LessonStoreManager.saveLessons
import com.schoolapp.cleverclass.ui.theme.CleverClassTheme
import com.schoolapp.cleverclass.ui.theme.InputPrimaryColor
import com.schoolapp.cleverclass.ui.theme.InputSecondaryColor
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.util.Locale
private lateinit var activityType : String
private lateinit var activityState : String
private val listOfDays = listOf("Mo", "Di", "Mi", "Do", "Fr")
//Custom ripple to remove effect when touching tabs
private class CustomRippleTheme : RippleTheme {
@Composable
override fun defaultColor(): Color = Color.Unspecified
@@ -100,11 +100,13 @@ class TimeTableSetupActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//Defines setup type --> Time vs. Day
activityType = intent.getStringExtra(TYPE_KEY).toString()
//Defines curent day of week
activityState = intent.getStringExtra(STATE_KEY).toString()
//Load lessons of defined day from activityState
var lessons = listOf<LessonData>()
if (activityType == "DaySetup") {
CoroutineScope(Dispatchers.IO).launch {
getLessons(this@TimeTableSetupActivity, listOfDays[activityState.toInt()]).collect { savedLessons ->
@@ -131,6 +133,7 @@ class TimeTableSetupActivity : ComponentActivity() {
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun TimeTableSetupContent(activity: ComponentActivity, loadedLessons: List<LessonData>){
//One-time definition of the inputField colorscheme
val inputFieldColors = TextFieldDefaults.outlinedTextFieldColors(
textColor = MaterialTheme.colorScheme.onPrimaryContainer,
containerColor = MaterialTheme.colorScheme.secondaryContainer,
@@ -143,32 +146,36 @@ fun TimeTableSetupContent(activity: ComponentActivity, loadedLessons: List<Lesso
unfocusedBorderColor = Color.Transparent
)
//Declaration of most sharedPreferences-stored data
val sharedPreferences = activity.getSharedPreferences("TimeTable", Context.MODE_PRIVATE)
val editor = sharedPreferences.edit()
//Length of one lesson
var lessonLength by remember {
mutableStateOf(sharedPreferences.getInt("lessonLength", 0).toString())
}
//Number of breaks on one day
var breakAmnt by remember {
mutableStateOf(sharedPreferences.getInt("breakAmnt", 0).toString())
}
//Beginning time of the first lesson (Format: hh.mm)
var firstLesson by remember {
mutableStateOf(sharedPreferences.getFloat("firstLesson", 0.0f))
}
//Value to determine whether the first setup will be loaded again
var setupDone by remember {
mutableStateOf(sharedPreferences.getBoolean("setupDone", false))
}
//AlertDialog
var showInfo by remember {
mutableStateOf(false)
}
var showDeleteConfirmation by remember {
mutableStateOf(false)
}
//Variable for loaded lessons from onCreate()
var lessons by remember {
mutableStateOf(loadedLessons)
}
@@ -179,7 +186,14 @@ fun TimeTableSetupContent(activity: ComponentActivity, loadedLessons: List<Lesso
colors = TopAppBarDefaults.centerAlignedTopAppBarColors(MaterialTheme.colorScheme.primaryContainer),
title = { Text(text = "") },
navigationIcon = {
IconButton(onClick = { activity.finish() }) {
IconButton(
onClick = {
activity.finish()
val intent = Intent(activity, StundenplanActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
startActivity(activity, intent, null)
}
) {
Icon(
imageVector = Icons.Filled.ArrowBack,
contentDescription = null,
@@ -197,6 +211,7 @@ fun TimeTableSetupContent(activity: ComponentActivity, loadedLessons: List<Lesso
.fillMaxHeight()
.verticalScroll(rememberScrollState())
) {
//Background
Surface(
color = MaterialTheme.colorScheme.primaryContainer,
shape = RoundedCornerShape(20),
@@ -205,6 +220,7 @@ fun TimeTableSetupContent(activity: ComponentActivity, loadedLessons: List<Lesso
Column(horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.padding(16.dp)
) {
//Title
Row(verticalAlignment = Alignment.CenterVertically) {
Text(
text = "Stundenplan Setup",
@@ -215,6 +231,7 @@ fun TimeTableSetupContent(activity: ComponentActivity, loadedLessons: List<Lesso
Spacer(modifier = Modifier.weight(1f))
//Info Button --> AlertDialog
IconButton(onClick = { showInfo = !showInfo }) {
Icon(
imageVector = Icons.Outlined.Info,
@@ -222,20 +239,13 @@ fun TimeTableSetupContent(activity: ComponentActivity, loadedLessons: List<Lesso
tint = MaterialTheme.colorScheme.onPrimaryContainer
)
}
if (activityType == "Settings")
IconButton(onClick = { showDeleteConfirmation = !showDeleteConfirmation }) {
Icon(
imageVector = Icons.Outlined.Delete,
contentDescription = null,
modifier = Modifier.size(28.dp),
tint = MaterialTheme.colorScheme.onPrimaryContainer
)
}
}
Spacer(modifier = Modifier.height(16.dp))
//Setup for basic time data (lesson/break length etc.)
if (activityType == "TimeSetup") {
//Time input begin of first lesson
Text(
text = "Beginn der 1. Stunde",
modifier = Modifier.fillMaxWidth(),
@@ -268,6 +278,7 @@ fun TimeTableSetupContent(activity: ComponentActivity, loadedLessons: List<Lesso
Spacer(modifier = Modifier.height(16.dp))
//Duration of one lesson
OutlinedTextField(
value = lessonLength,
onValueChange = { lessonLength = it },
@@ -282,6 +293,7 @@ fun TimeTableSetupContent(activity: ComponentActivity, loadedLessons: List<Lesso
Spacer(modifier = Modifier.height(16.dp))
//Input amount of breaks
OutlinedTextField(
value = breakAmnt,
onValueChange = { breakAmnt = it},
@@ -294,17 +306,20 @@ fun TimeTableSetupContent(activity: ComponentActivity, loadedLessons: List<Lesso
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.NumberPassword)
)
//Input of length and start time for each break
if (breakAmnt != "") {
//declaration of sharedPreferences for break data
for (i in 0 until breakAmnt.toInt()) {
var currentBrakeStartTime by remember{
mutableStateOf(sharedPreferences.getFloat("Brake${i}StartTime", 0.0f))
var currentBreakStartTime by remember{
mutableStateOf(sharedPreferences.getFloat("break${i}StartTime", 0.0f))
}
var currentBrakeLength by remember{
mutableStateOf(sharedPreferences.getInt("Brake${i}Length", 0).toString())
var currentBreakLength by remember{
mutableStateOf(sharedPreferences.getInt("break${i}Length", 0).toString())
}
Spacer(modifier = Modifier.height(16.dp))
//Input start time (break)
Text(
text = "Startzeit der ${i + 1}. Pause:",
modifier = Modifier.fillMaxWidth(),
@@ -316,8 +331,8 @@ fun TimeTableSetupContent(activity: ComponentActivity, loadedLessons: List<Lesso
val mHour = c.get(Calendar.HOUR_OF_DAY)
val mMinute = c.get(Calendar.MINUTE)
val timePickerDialog = TimePickerDialog(activity, TimePickerDialog.OnTimeSetListener(function = { view, h, m ->
currentBrakeStartTime = h.toFloat() + (m.toFloat() / 100)
editor.putFloat("Brake${i}StartTime", currentBrakeStartTime)
currentBreakStartTime = h.toFloat() + (m.toFloat() / 100)
editor.putFloat("break${i}StartTime", currentBreakStartTime)
}), mHour, mMinute, true)
timePickerDialog.show()
},
@@ -329,7 +344,7 @@ fun TimeTableSetupContent(activity: ComponentActivity, loadedLessons: List<Lesso
val decimalFormat = DecimalFormat("00.00", symbols)
Text(
text = decimalFormat.format(currentBrakeStartTime) + " Uhr ",
text = decimalFormat.format(currentBreakStartTime) + " Uhr ",
color = MaterialTheme.colorScheme.onPrimaryContainer,
style = MaterialTheme.typography.labelMedium
)
@@ -339,11 +354,14 @@ fun TimeTableSetupContent(activity: ComponentActivity, loadedLessons: List<Lesso
Spacer(modifier = Modifier.height(5.dp))
//Input duration (break)
OutlinedTextField(
value = currentBrakeLength,
value = currentBreakLength,
onValueChange = {
currentBrakeLength = it
editor.putInt("Brake${i}Length", currentBrakeLength.toInt())},
currentBreakLength = it
if (currentBreakLength != "") {
editor.putInt("break${i}Length", currentBreakLength.toInt())
}},
label = { Text(text = "Länge der ${i + 1}. Pause in min") },
modifier = Modifier.fillMaxWidth(),
singleLine = true,
@@ -358,9 +376,18 @@ fun TimeTableSetupContent(activity: ComponentActivity, loadedLessons: List<Lesso
Spacer(modifier = Modifier.height(10.dp))
Row {
//Go back to StundenplanActivity
FilledTonalButton(
onClick = {
editor.putInt("lessonLength", lessonLength.toInt())
editor.putInt("breakAmnt", breakAmnt.toInt())
editor.apply()
activity.finish()
//Reopen of activity so values will be updated
val intent = Intent(activity, StundenplanActivity::class.java)
//Remove previous StundenplanActivity from activity stack so when going back later it won't exist twice
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
startActivity(activity, intent, null)
},
modifier = Modifier
.padding(5.dp)
@@ -377,6 +404,7 @@ fun TimeTableSetupContent(activity: ComponentActivity, loadedLessons: List<Lesso
.width(5.dp)
)
//Move on to DaySetup
Button(
onClick = {
editor.putInt("lessonLength", lessonLength.toInt())
@@ -385,6 +413,7 @@ fun TimeTableSetupContent(activity: ComponentActivity, loadedLessons: List<Lesso
activity.finish()
val intent = Intent(activity, TimeTableSetupActivity::class.java).apply {
putExtra(TimeTableSetupActivity.TYPE_KEY, "DaySetup")
//State 0 for indexing days (0..4)
putExtra(TimeTableSetupActivity.STATE_KEY, "0")
}
startActivity(activity, intent, null)
@@ -400,15 +429,20 @@ fun TimeTableSetupContent(activity: ComponentActivity, loadedLessons: List<Lesso
}
}
}
//DaySetup for information on the lessons (teacher, subject, amount per day, etc.)
else if (activityType == "DaySetup") {
var state by remember {
//State that defines the current day (e.g. for LessonData or the Tab highlighting)
val state by remember {
mutableStateOf(activityState.toInt())
}
//SharedPreferences for the amount of hours of each day (indexed by state --> 0..4)
var currentLessonAmount by remember {
mutableStateOf(sharedPreferences.getInt("lessonAmount${listOfDays[state]}", 0).toString())
}
//TabRow with Tabs to visualize the days; no onClick fun and thus the custom ripple theme
CompositionLocalProvider(LocalRippleTheme provides CustomRippleTheme()) {
TabRow(selectedTabIndex = state,
containerColor = MaterialTheme.colorScheme.primaryContainer) {
@@ -429,6 +463,7 @@ fun TimeTableSetupContent(activity: ComponentActivity, loadedLessons: List<Lesso
Spacer(modifier = Modifier.height(16.dp))
//Input of the amount of lessons on the current day
OutlinedTextField(
value = currentLessonAmount,
onValueChange = {
@@ -449,70 +484,88 @@ fun TimeTableSetupContent(activity: ComponentActivity, loadedLessons: List<Lesso
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.NumberPassword)
)
//Creation of TextField for further input for the lessons themselves + saveUsage into DataStore --> saveLessonUsage(...)
if (currentLessonAmount != "") {
for (i in lessons.size until currentLessonAmount.toInt()) {
lessons = lessons + LessonData("", "", "")
}
while (currentLessonAmount.toInt() < lessons.size) {
lessons = lessons.drop(1)
}
lessons.forEachIndexed() { index, lessonData ->
var currentSubject by remember {
mutableStateOf(lessonData.subject)
if (currentLessonAmount != "0") {
//Creation/Removal of the current amount of LessonData object depending pn currentLessonAmount
for (i in lessons.size until currentLessonAmount.toInt()) {
lessons = lessons + LessonData("", "", "")
}
var currentTeacher by remember {
mutableStateOf(lessonData.teacher)
while (currentLessonAmount.toInt() < lessons.size) {
lessons = lessons.drop(1)
}
var currentRoom by remember {
mutableStateOf(lessonData.room)
lessons.forEachIndexed() { index, lessonData ->
//Input variables
var currentSubject by remember {
mutableStateOf(lessonData.subject)
}
var currentTeacher by remember {
mutableStateOf(lessonData.teacher)
}
var currentRoom by remember {
mutableStateOf(lessonData.room)
}
//Input of the subject of the current lesson
OutlinedTextField(
value = currentSubject,
onValueChange = {
currentSubject = it
lessonData.subject = it
saveLessonsUsage(activity, lessons, state)
},
label = { Text(text = "Fach der ${index + 1}. Stunde") },
modifier = Modifier.fillMaxWidth(),
singleLine = true,
shape = RoundedCornerShape(20),
textStyle = MaterialTheme.typography.labelMedium,
colors = inputFieldColors,
)
//Input of the room of the current lesson
OutlinedTextField(
value = currentRoom,
onValueChange = {
currentRoom = it
lessonData.room = it
saveLessonsUsage(activity, lessons, state)
},
label = { Text(text = "Raum der ${index + 1}. Stunde") },
modifier = Modifier.fillMaxWidth(),
singleLine = true,
shape = RoundedCornerShape(20),
textStyle = MaterialTheme.typography.labelMedium,
colors = inputFieldColors,
)
//Input of the teacher of the current lesson
OutlinedTextField(
value = currentTeacher,
onValueChange = {
currentTeacher = it
lessonData.teacher = it
saveLessonsUsage(activity, lessons, state)
},
label = { Text(text = "Lehrer der ${index + 1}. Stunde") },
modifier = Modifier.fillMaxWidth(),
singleLine = true,
shape = RoundedCornerShape(20),
textStyle = MaterialTheme.typography.labelMedium,
colors = inputFieldColors,
)
}
OutlinedTextField(
value = currentSubject,
onValueChange = {
currentSubject = it
lessonData.subject = it
saveLessonsUsage(activity, lessons, state)
},
label = { Text(text = "Fach der ${index + 1}. Stunde") },
modifier = Modifier.fillMaxWidth(),
singleLine = true,
shape = RoundedCornerShape(20),
textStyle = MaterialTheme.typography.labelMedium,
colors = inputFieldColors,
)
OutlinedTextField(
value = currentTeacher,
onValueChange = {
currentTeacher = it
lessonData.teacher = it
saveLessonsUsage(activity, lessons, state)
},
label = { Text(text = "Lehrer der ${index + 1}. Stunde") },
modifier = Modifier.fillMaxWidth(),
singleLine = true,
shape = RoundedCornerShape(20),
textStyle = MaterialTheme.typography.labelMedium,
colors = inputFieldColors,
)
OutlinedTextField(
value = currentRoom,
onValueChange = {
currentRoom = it
lessonData.room = it
saveLessonsUsage(activity, lessons, state)
},
label = { Text(text = "Raum der ${index + 1}. Stunde") },
modifier = Modifier.fillMaxWidth(),
singleLine = true,
shape = RoundedCornerShape(20),
textStyle = MaterialTheme.typography.labelMedium,
colors = inputFieldColors,
)
}
//save an empty list into DataStore currentLessonAmount == 0
else {
saveLessonsUsage(activity, emptyList(), state)
}
}
Spacer(modifier = Modifier.height(16.dp))
//Checkbox on the friday page (state == 4) to prevent setup from automatically openening next time
if (state == 4) {
Box(
modifier = Modifier
@@ -531,16 +584,19 @@ fun TimeTableSetupContent(activity: ComponentActivity, loadedLessons: List<Lesso
}
}
//Go back
Row {
FilledTonalButton(
onClick = {
activity.finish()
//To TimeSetup
if (state == 0) {
val intent = Intent(activity, TimeTableSetupActivity::class.java).apply {
putExtra(TimeTableSetupActivity.TYPE_KEY, "TimeSetup")
}
startActivity(activity, intent, null)
}
//To the day before (STATE_KEY -= 1)
else {
val intent = Intent(activity, TimeTableSetupActivity::class.java).apply {
putExtra(TimeTableSetupActivity.TYPE_KEY, "DaySetup")
@@ -565,9 +621,11 @@ fun TimeTableSetupContent(activity: ComponentActivity, loadedLessons: List<Lesso
.width(5.dp)
)
//Go forwards
Button(
onClick = {
activity.finish()
//To next day (STATE_KEY += 1)
if (state != 4) {
val intent = Intent(activity, TimeTableSetupActivity::class.java).apply {
putExtra(TimeTableSetupActivity.TYPE_KEY, "DaySetup")
@@ -575,8 +633,14 @@ fun TimeTableSetupContent(activity: ComponentActivity, loadedLessons: List<Lesso
}
startActivity(activity, intent, null)
}
//To Stundenplan
else {
editor.putBoolean("setupDone", setupDone)
//Reopen of activity so values will be updated
val intent = Intent(activity, StundenplanActivity::class.java)
//Remove previous StundenplanActivity from activity stack so when going back later it won't exist twice
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
startActivity(activity, intent, null)
}
editor.apply()
},
@@ -596,6 +660,7 @@ fun TimeTableSetupContent(activity: ComponentActivity, loadedLessons: List<Lesso
}
}
//AlertDialog to inform the user of the possibility of changing all inputs later
if (showInfo) {
AlertDialog(
onDismissRequest = { showInfo = false },
@@ -618,53 +683,9 @@ fun TimeTableSetupContent(activity: ComponentActivity, loadedLessons: List<Lesso
.padding(5.dp)
)
}
if (showDeleteConfirmation) {
AlertDialog(
onDismissRequest = { showDeleteConfirmation = false },
text = {
Text(
text = "Möchten Sie wirklich die Anmeldedaten löschen?",
color = MaterialTheme.colorScheme.onPrimaryContainer,
style = MaterialTheme.typography.labelMedium
)
},
confirmButton = {
Row(modifier = Modifier.fillMaxWidth()){
Text(
text = "Bestätigen",
color = MaterialTheme.colorScheme.secondary,
style = MaterialTheme.typography.labelMedium,
modifier = Modifier.clickable {
editor.putString("maxLessons", "")
editor.apply()
showDeleteConfirmation = false
activity.finish()
}
)
Spacer(modifier = Modifier.weight(1f))
Text(
text = "Abbrechen",
color = MaterialTheme.colorScheme.secondary,
style = MaterialTheme.typography.labelMedium,
modifier = Modifier.clickable { showDeleteConfirmation = false }
)
}
},
containerColor = MaterialTheme.colorScheme.primaryContainer
)
}
}
@Composable
fun TestButton(text: String, onClick: ()-> Unit){
Button(onClick = onClick,) {
Text(text = text)
}
}
//Function that implements the save of List<LessonData>
fun saveLessonsUsage(context: Context, lessons: List<LessonData>, int: Int) {
CoroutineScope(Dispatchers.IO).launch {
saveLessons(context, lessons, listOfDays[int])