Started StundenplanActivity
began with the implementation of sharedPreferences added LessonStoreManager added TimeTableSetupActivity (-> + entries in the AndroidManifest.xml & strings.xml) committed version of "Stundenplan" is unfinished and malfunctional (switching to Laptop for holidays)
This commit is contained in:
@@ -40,6 +40,11 @@
|
||||
android:exported="false"
|
||||
android:label="@string/title_activity_noten"
|
||||
android:theme="@style/Theme.CleverClass" />
|
||||
<activity
|
||||
android:name=".TimeTableSetupActivity"
|
||||
android:exported="false"
|
||||
android:label="@string/title_activity_timetable_setup"
|
||||
android:theme="@style/Theme.CleverClass" />
|
||||
<activity
|
||||
android:name=".StundenplanActivity"
|
||||
android:exported="false"
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.schoolapp.cleverclass
|
||||
|
||||
import android.content.Context
|
||||
import androidx.datastore.core.DataStore
|
||||
import androidx.datastore.preferences.core.Preferences
|
||||
import androidx.datastore.preferences.core.edit
|
||||
import androidx.datastore.preferences.core.stringPreferencesKey
|
||||
import androidx.datastore.preferences.preferencesDataStore
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
object LessonStoreManager {
|
||||
private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "lesson_preferences")
|
||||
|
||||
suspend fun saveLessons(context: Context, lessons: List<LessonData>, day: String) {
|
||||
context.dataStore.edit { preferences ->
|
||||
val json = Gson().toJson(lessons)
|
||||
preferences[stringPreferencesKey(day)] = json
|
||||
}
|
||||
}
|
||||
|
||||
fun getLessons(context: Context, day: String): Flow<List<LessonData>> {
|
||||
return context.dataStore.data.map { preferences ->
|
||||
val json = preferences[stringPreferencesKey(day)] ?: return@map emptyList()
|
||||
val type = object : TypeToken<List<LessonData>>() {}.type
|
||||
Gson().fromJson(json, type)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,15 @@
|
||||
package com.schoolapp.cleverclass
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.compose.setContent
|
||||
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.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.ArrowBack
|
||||
@@ -18,19 +22,47 @@ 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.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.schoolapp.cleverclass.LessonStoreManager.getLessons
|
||||
import com.schoolapp.cleverclass.ui.theme.CleverClassTheme
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
private val listOfDays = listOf("mon", "tue", "wed", "thu", "fri", "sat", "sun")
|
||||
private val lessonGrabberIndex = 0
|
||||
|
||||
class StundenplanActivity : ComponentActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
val sharedPreferences = this.getSharedPreferences("TimeTable", Context.MODE_PRIVATE)
|
||||
val maxLessons = sharedPreferences.getString("maxLessons", "").toString()
|
||||
val lessonLength = sharedPreferences.getString("lessonLength", "").toString()
|
||||
|
||||
setContent {
|
||||
CleverClassTheme {
|
||||
Surface(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
color = MaterialTheme.colorScheme.background
|
||||
) {
|
||||
println(maxLessons)
|
||||
//println(lessonLength)
|
||||
if (maxLessons.isEmpty() || lessonLength.isEmpty()) {
|
||||
val intent = Intent(this@StundenplanActivity, TimeTableSetupActivity::class.java).apply {
|
||||
putExtra(TimeTableSetupActivity.TYPE_KEY, "FirstSetup")
|
||||
}
|
||||
startActivity(intent)
|
||||
}
|
||||
|
||||
StundenplanContent(activity = this)
|
||||
}
|
||||
}
|
||||
@@ -64,7 +96,46 @@ fun StundenplanContent(activity: ComponentActivity){
|
||||
)
|
||||
|
||||
Column() {
|
||||
|
||||
listOfDays.forEach() {currentDay ->
|
||||
Day(currentDay)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class LessonData(
|
||||
val subject: String,
|
||||
val teacher: String,
|
||||
val 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() {
|
||||
Lesson(subject = it.subject, teacher = it.teacher, room = it.room)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun Lesson(subject: String, teacher: String, room: String) {
|
||||
Box(modifier = Modifier
|
||||
.size(200.dp, 100.dp)
|
||||
.padding(3.dp)
|
||||
) {
|
||||
Text(modifier = Modifier.align(Alignment.Center),
|
||||
text = "$subject\n@$room\n/w$teacher")
|
||||
}
|
||||
}
|
||||
|
||||
fun currentDay(): String {
|
||||
return "hi"
|
||||
}
|
||||
@@ -0,0 +1,316 @@
|
||||
package com.schoolapp.cleverclass
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.compose.foundation.Image
|
||||
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.layout.size
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
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.Info
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.OutlinedTextField
|
||||
import androidx.compose.material3.Surface
|
||||
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.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.res.painterResource
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.text.input.PasswordVisualTransformation
|
||||
import androidx.compose.ui.text.input.VisualTransformation
|
||||
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
|
||||
|
||||
private lateinit var activityType : String
|
||||
|
||||
class TimeTableSetupActivity : ComponentActivity() {
|
||||
companion object{
|
||||
const val TYPE_KEY = "type_key"
|
||||
}
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
activityType = intent.getStringExtra(TYPE_KEY).toString()
|
||||
|
||||
setContent {
|
||||
CleverClassTheme {
|
||||
Surface(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
color = MaterialTheme.colorScheme.background
|
||||
) {
|
||||
TimeTableSetupContent(activity = this)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Content of TimeTableSetup
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun TimeTableSetupContent(activity: ComponentActivity){
|
||||
val inputFieldColors = TextFieldDefaults.outlinedTextFieldColors(
|
||||
textColor = MaterialTheme.colorScheme.onPrimaryContainer,
|
||||
containerColor = MaterialTheme.colorScheme.secondaryContainer,
|
||||
cursorColor = InputPrimaryColor,
|
||||
selectionColors = TextSelectionColors(
|
||||
handleColor = InputPrimaryColor,
|
||||
backgroundColor = InputSecondaryColor
|
||||
),
|
||||
focusedBorderColor = InputSecondaryColor,
|
||||
unfocusedBorderColor = Color.Transparent
|
||||
)
|
||||
|
||||
val sharedPreferences = activity.getSharedPreferences("TimeTable", Context.MODE_PRIVATE)
|
||||
val editor = sharedPreferences.edit()
|
||||
|
||||
var maxLessons by remember {
|
||||
mutableStateOf(sharedPreferences.getString("maxLessons", "-1").toString())
|
||||
}
|
||||
var lessonLength by remember {
|
||||
mutableStateOf(sharedPreferences.getString("lessonLength", "-1").toString())
|
||||
}
|
||||
var showPassword by remember {
|
||||
mutableStateOf(false)
|
||||
}
|
||||
|
||||
var showInfo by remember {
|
||||
mutableStateOf(false)
|
||||
}
|
||||
var showDeleteConfirmation by remember {
|
||||
mutableStateOf(false)
|
||||
}
|
||||
|
||||
Column {
|
||||
TopAppBar(
|
||||
colors = TopAppBarDefaults.centerAlignedTopAppBarColors(MaterialTheme.colorScheme.primaryContainer),
|
||||
title = { Text(text = "") },
|
||||
navigationIcon = {
|
||||
IconButton(onClick = { activity.finish() }) {
|
||||
Icon(
|
||||
imageVector = Icons.Filled.ArrowBack,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(28.dp),
|
||||
tint = MaterialTheme.colorScheme.onPrimaryContainer
|
||||
)
|
||||
}
|
||||
},
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
|
||||
Column(
|
||||
verticalArrangement = Arrangement.Center,
|
||||
modifier = Modifier
|
||||
.fillMaxHeight()
|
||||
.verticalScroll(rememberScrollState())
|
||||
) {
|
||||
Surface(
|
||||
color = MaterialTheme.colorScheme.primaryContainer,
|
||||
shape = RoundedCornerShape(20),
|
||||
modifier = Modifier.padding(16.dp)
|
||||
) {
|
||||
Column(horizontalAlignment = Alignment.CenterHorizontally,
|
||||
modifier = Modifier.padding(16.dp)
|
||||
) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
Text(
|
||||
text = "Stundenplan Setup",
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = MaterialTheme.colorScheme.onPrimaryContainer,
|
||||
modifier = Modifier.padding(10.dp)
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
|
||||
if (activityType == "Settings")
|
||||
IconButton(onClick = { showDeleteConfirmation = !showDeleteConfirmation }) {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.Delete,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(28.dp),
|
||||
tint = MaterialTheme.colorScheme.onPrimaryContainer
|
||||
)
|
||||
}
|
||||
else if (activityType == "FirstSetup")
|
||||
IconButton(onClick = { showInfo = !showInfo }) {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.Info,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.onPrimaryContainer
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
OutlinedTextField(
|
||||
value = maxLessons,
|
||||
onValueChange = { maxLessons = it },
|
||||
placeholder = {
|
||||
Text(
|
||||
text = "Maximale Stundenanzahl an einem Tag",
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = MaterialTheme.colorScheme.primaryContainer
|
||||
)
|
||||
},
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
singleLine = true,
|
||||
shape = RoundedCornerShape(20),
|
||||
textStyle = MaterialTheme.typography.labelMedium,
|
||||
colors = inputFieldColors
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
OutlinedTextField(
|
||||
value = lessonLength,
|
||||
onValueChange = { lessonLength = it },
|
||||
placeholder = {
|
||||
Text(
|
||||
text = "Länge einer Schulstunde",
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = MaterialTheme.colorScheme.primaryContainer
|
||||
)
|
||||
},
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
singleLine = true,
|
||||
shape = RoundedCornerShape(20),
|
||||
textStyle = MaterialTheme.typography.labelMedium,
|
||||
colors = inputFieldColors,
|
||||
visualTransformation = if(showPassword) VisualTransformation.None else PasswordVisualTransformation(),
|
||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
|
||||
trailingIcon = {
|
||||
IconButton(onClick = { showPassword = !showPassword })
|
||||
{
|
||||
Image(
|
||||
painter = painterResource(
|
||||
id = if(showPassword)
|
||||
R.drawable.baseline_visibility_24
|
||||
else
|
||||
R.drawable.baseline_visibility_off_24
|
||||
),
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(10.dp))
|
||||
|
||||
Box(
|
||||
contentAlignment = Alignment.Center,
|
||||
modifier = Modifier.clickable {
|
||||
editor.putString("maxLessons", maxLessons)
|
||||
editor.putString("lessonLength", lessonLength)
|
||||
editor.apply()
|
||||
activity.finish()
|
||||
}
|
||||
) {
|
||||
Text(
|
||||
text = "Speichen",
|
||||
color = MaterialTheme.colorScheme.secondary,
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
modifier = Modifier.padding(10.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (showInfo) {
|
||||
AlertDialog(
|
||||
onDismissRequest = { showInfo = false },
|
||||
text = {
|
||||
Text(
|
||||
text = "Der Benutzername und das Passwort können später in den Einstellungen geändert werden",
|
||||
color = MaterialTheme.colorScheme.onPrimaryContainer,
|
||||
style = MaterialTheme.typography.labelMedium)
|
||||
},
|
||||
confirmButton = {
|
||||
Text(
|
||||
text = "Schließen",
|
||||
color = MaterialTheme.colorScheme.secondary,
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
modifier = Modifier.clickable { showInfo = false }
|
||||
)
|
||||
},
|
||||
containerColor = MaterialTheme.colorScheme.primaryContainer,
|
||||
modifier = Modifier
|
||||
.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("username", "")
|
||||
editor.putString("password", "")
|
||||
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
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -9,4 +9,5 @@
|
||||
<string name="title_activity_dsbactivity">DSBActivity</string>
|
||||
<string name="title_activity_dsbday_view">DSBDayViewActivity</string>
|
||||
<string name="title_activity_dsblogin">DSBLoginActivity</string>
|
||||
<string name="title_activity_timetable_setup">TimetableSetupActivity</string>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user