Compare commits

..

12 Commits

Author SHA1 Message Date
Paul
442ef70b8d update AboutActivity 2024-10-24 13:59:01 +02:00
BuildTools
ec3a95fc2d Merge remote-tracking branch 'origin/master' 2024-10-14 15:26:13 +02:00
BuildTools
b07cd27fce Why tf is "Index": 0 @ index = 1 and "Index": 2 @ index = 0 2024-10-14 15:25:58 +02:00
matthias
39c037a9ab delete empty line 2024-07-05 17:44:51 +02:00
matthias
f6956349e0 Small adjustment
3 month --> 3 months
2024-06-26 06:59:01 +02:00
BuildTools
a41bd9cbb3 Small adjustment 2024-06-21 16:52:28 +02:00
BuildTools
0db1e78cd4 Small adjustments 2024-06-16 13:16:56 +02:00
matthias
7bdcb7e3fb Added restart of app when first setup isn't done
when going back via phone feature, user sees the empty timetable
2024-06-09 23:46:58 +02:00
matthias
d36cadeb18 Fixed typo 2024-06-09 23:45:32 +02:00
BuildTools
1056dc39bf Add deleteAllData 2024-06-09 21:58:28 +02:00
matthias
15cadb76c6 Minor appearance adjustments
added scaling with 1.1f(lesson indexes & "Pause") / 0.8f(times)
2024-06-09 13:22:00 +02:00
matthias
41b54f15ea Major Bugfix
fixed removal of lessons
2024-06-09 13:20:31 +02:00
8 changed files with 169 additions and 37 deletions

View File

@@ -23,6 +23,7 @@ android {
buildTypes { buildTypes {
release { release {
isMinifyEnabled = false isMinifyEnabled = false
isDebuggable = false
proguardFiles( proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"), getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro" "proguard-rules.pro"

View File

@@ -83,7 +83,7 @@ fun AboutContent(activity: ComponentActivity){
{ {
AboutTextElement("This Product is published under the\nGNU General Public License\nVersion 3, 29 June 2007", 16.dp) AboutTextElement("This Product is published under the\nGNU General Public License\nVersion 3, 29 June 2007", 16.dp)
AboutTextElement("Developed by:\n- Paul Posch\n- Matthias Meyer\n- Jakub Szarko\n- Emilian Bührer", 32.dp) AboutTextElement("Developed by:\n- Paul Posch\n- Matthias Meyer\n- Jakub Szarko\n- Emilian Bührer", 32.dp)
AboutTextElement("Fun Facts:\nThis app consists of 2.873 lines of code\nThe repository is 413KB big\nThe development took about 3 month", 64.dp) //TODO: Update before launch AboutTextElement("Fun Facts:\nThis app consists of 4.189 lines of code\nThe repository is 768KB big\nThe development took about 3 months", 64.dp)
Spacer(modifier = Modifier.height(32.dp)) Spacer(modifier = Modifier.height(32.dp))
Divider() Divider()
@@ -98,7 +98,7 @@ fun AboutContent(activity: ComponentActivity){
) { ) {
Row { Row {
Text( Text(
text = "Unterstütze die Entwickler", text = "Support the Devs",
style = MaterialTheme.typography.bodySmall, style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onBackground, color = MaterialTheme.colorScheme.onBackground,
modifier = Modifier.padding(16.dp) modifier = Modifier.padding(16.dp)

View File

@@ -127,7 +127,19 @@ private fun decompressGZIPAndDecodeBase64(compressedData: String): String {
private fun downloadImagesTask(jsonResponse: JSONObject, mainDir : File) : Int { private fun downloadImagesTask(jsonResponse: JSONObject, mainDir : File) : Int {
clearFolder(mainDir) clearFolder(mainDir)
val jsonDaysObject = jsonResponse.getJSONArray("ResultMenuItems").getJSONObject(0).getJSONArray("Childs").getJSONObject(0).getJSONObject("Root").getJSONArray("Childs") var jsonDaysObject = jsonResponse.getJSONArray("ResultMenuItems")
for (i in 0 until jsonDaysObject.length()) {
if (jsonDaysObject.getJSONObject(i).get("Index") == 0) {
jsonDaysObject = jsonDaysObject.getJSONObject(i).getJSONArray("Childs")
break
}
}
for (i in 0 until jsonDaysObject.length()) {
if (jsonDaysObject.getJSONObject(i).get("Index") == 0) {
jsonDaysObject = jsonDaysObject.getJSONObject(i).getJSONObject("Root").getJSONArray("Childs")
break
}
}
for (d in 0 until jsonDaysObject.length()) { for (d in 0 until jsonDaysObject.length()) {
val jsonDayObject = jsonDaysObject.getJSONObject(d) val jsonDayObject = jsonDaysObject.getJSONObject(d)
@@ -201,20 +213,6 @@ private fun createDataFolder(context: Context) : File {
return folder return folder
} }
private fun clearFolder(directory: File) {
if (directory.exists()) {
val files = directory.listFiles()
if (files != null) {
for (file in files) {
if (file.isDirectory) {
clearFolder(file)
}
file.delete()
}
}
}
}
private fun isInternetAvailable(context: Context): Boolean { private fun isInternetAvailable(context: Context): Boolean {
val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val network = connectivityManager.activeNetwork val network = connectivityManager.activeNetwork

View File

@@ -24,6 +24,7 @@ import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Divider import androidx.compose.material3.Divider
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
@@ -35,8 +36,10 @@ import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
@@ -64,6 +67,10 @@ fun SettingsContent(activity: ComponentActivity) {
val sharedPreferences = activity.getSharedPreferences("Settings", Context.MODE_PRIVATE) val sharedPreferences = activity.getSharedPreferences("Settings", Context.MODE_PRIVATE)
val editor = sharedPreferences.edit() val editor = sharedPreferences.edit()
var showDeleteConfirmation by remember {
mutableStateOf(false)
}
Column(modifier = Modifier.fillMaxSize()) { Column(modifier = Modifier.fillMaxSize()) {
// Top AppBar // Top AppBar
TopAppBar( TopAppBar(
@@ -94,14 +101,14 @@ fun SettingsContent(activity: ComponentActivity) {
.weight(1f) .weight(1f)
.verticalScroll(rememberScrollState()) .verticalScroll(rememberScrollState())
.fillMaxWidth() .fillMaxWidth()
) { ) {
Setting(text = "Stundenplan", sharedPreferences, editor) Setting(text = "Stundenplan", sharedPreferences, editor)
Setting(text = "Noten", sharedPreferences, editor) Setting(text = "Noten", sharedPreferences, editor)
Setting(text = "Periodensystem", sharedPreferences, editor) Setting(text = "Periodensystem", sharedPreferences, editor)
Setting(text = "Mebis", sharedPreferences, editor)
Setting(text = "DSBmobile", sharedPreferences, editor) Setting(text = "DSBmobile", sharedPreferences, editor)
Setting(text = "Mebis", sharedPreferences, editor)
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(16.dp))
Divider() Divider()
Box( Box(
modifier = Modifier modifier = Modifier
@@ -120,6 +127,19 @@ fun SettingsContent(activity: ComponentActivity) {
modifier = Modifier.padding(16.dp) modifier = Modifier.padding(16.dp)
) )
} }
Divider()
Box(
modifier = Modifier
.fillMaxWidth()
.clickable { showDeleteConfirmation = true }
) {
Text(
text = "Alle Daten löschen",
color = MaterialTheme.colorScheme.onBackground,
style = MaterialTheme.typography.labelMedium,
modifier = Modifier.padding(16.dp)
)
}
} }
// About Button // About Button
@@ -150,6 +170,43 @@ fun SettingsContent(activity: ComponentActivity) {
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
} }
} }
if(showDeleteConfirmation){
AlertDialog(
onDismissRequest = { showDeleteConfirmation = false },
text = {
Text(
text = "Möchten Sie wirklich alle Daten aus dieser App löschen?\n" +
"Dieser Vorgang kann nicht rückgängig gemacht werden.",
color = MaterialTheme.colorScheme.onPrimaryContainer,
style = MaterialTheme.typography.labelMedium
)
},
confirmButton = {
Row(modifier = Modifier.fillMaxWidth()){
Text(
text = "Löschen",
color = MaterialTheme.colorScheme.secondary,
style = MaterialTheme.typography.labelMedium,
modifier = Modifier.clickable {
deleteAllData(activity)
showDeleteConfirmation = false
}
)
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 @Composable

View File

@@ -39,6 +39,7 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.scale
import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.core.content.ContextCompat.startActivity import androidx.core.content.ContextCompat.startActivity
@@ -212,7 +213,7 @@ fun StundenplanContent(activity: ComponentActivity, loadedLessons: List<List<Les
) )
} }
//Else creation of a Box containing all the information from the LessonData object //Else creation of a Box containing all the information from the LessonData object
else if (dailyLessons != emptyList<LessonData>()) { else if (dailyLessons != emptyList<LessonData>() && dailyLessons.size != extraIndex) {
LessonBox(subject = dailyLessons[extraIndex].subject, teacher = dailyLessons[extraIndex].teacher, room = dailyLessons[extraIndex].room) 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 counted up only here as it does only index the lessons and NOT the breaks
extraIndex++ extraIndex++
@@ -238,7 +239,7 @@ fun StundenplanContent(activity: ComponentActivity, loadedLessons: List<List<Les
text = { text = {
Text( Text(
text = "Die Breite der Spalten ist auf eine bestimmte Größe festgelegt.\n\n" + text = "Die Breite der Spalten ist auf eine bestimmte Größe festgelegt.\n\n" +
"Zu lange eingaben können horizontal gescrollt werden.", "Zu lange Eingaben können horizontal gescrollt werden.",
color = MaterialTheme.colorScheme.onPrimaryContainer, color = MaterialTheme.colorScheme.onPrimaryContainer,
style = MaterialTheme.typography.labelMedium) style = MaterialTheme.typography.labelMedium)
}, },
@@ -371,7 +372,9 @@ fun InfoColumn(loadedLessons: List<List<LessonData>>, breakAmnt: Int, breaksStar
) { ) {
//"Pause" String instead of indexing //"Pause" String instead of indexing
Text( Text(
modifier = Modifier.align(Alignment.Center), modifier = Modifier
.align(Alignment.Center)
.scale(1.1f),
text = "Pause", text = "Pause",
textDecoration = TextDecoration.Underline, textDecoration = TextDecoration.Underline,
style = MaterialTheme.typography.labelLarge style = MaterialTheme.typography.labelLarge
@@ -380,7 +383,8 @@ fun InfoColumn(loadedLessons: List<List<LessonData>>, breakAmnt: Int, breaksStar
Text( Text(
modifier = Modifier modifier = Modifier
.align(Alignment.BottomCenter) .align(Alignment.BottomCenter)
.padding(3.dp), .padding(3.dp)
.scale(0.8f),
text = formattedBreakTime, text = formattedBreakTime,
style = MaterialTheme.typography.labelMedium style = MaterialTheme.typography.labelMedium
) )
@@ -407,7 +411,9 @@ fun InfoColumn(loadedLessons: List<List<LessonData>>, breakAmnt: Int, breaksStar
) { ) {
//String with the indexing of the lessons //String with the indexing of the lessons
Text( Text(
modifier = Modifier.align(Alignment.Center), modifier = Modifier
.align(Alignment.Center)
.scale(1.1f),
text = "${i + 1 - lessonNegIncrement}:", text = "${i + 1 - lessonNegIncrement}:",
textDecoration = TextDecoration.Underline, textDecoration = TextDecoration.Underline,
style = MaterialTheme.typography.labelLarge style = MaterialTheme.typography.labelLarge
@@ -416,7 +422,8 @@ fun InfoColumn(loadedLessons: List<List<LessonData>>, breakAmnt: Int, breaksStar
Text( Text(
modifier = Modifier modifier = Modifier
.align(Alignment.BottomCenter) .align(Alignment.BottomCenter)
.padding(3.dp), .padding(3.dp)
.scale(0.8f),
text = substringHelper(extraIndex, firstLesson, lessonLength, lessonTimeIncrement), text = substringHelper(extraIndex, firstLesson, lessonLength, lessonTimeIncrement),
style = MaterialTheme.typography.labelMedium style = MaterialTheme.typography.labelMedium
) )

View File

@@ -189,10 +189,19 @@ fun TimeTableSetupContent(activity: ComponentActivity, loadedLessons: List<Lesso
IconButton( IconButton(
onClick = { onClick = {
activity.finish() activity.finish()
if (setupDone) {
val intent = Intent(activity, StundenplanActivity::class.java) val intent = Intent(activity, StundenplanActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
startActivity(activity, intent, null) startActivity(activity, intent, null)
} }
else {
val intent = Intent(activity, MainActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
startActivity(activity, intent, null)
}
}
) { ) {
Icon( Icon(
imageVector = Icons.Filled.ArrowBack, imageVector = Icons.Filled.ArrowBack,
@@ -383,11 +392,20 @@ fun TimeTableSetupContent(activity: ComponentActivity, loadedLessons: List<Lesso
editor.putInt("breakAmnt", breakAmnt.toInt()) editor.putInt("breakAmnt", breakAmnt.toInt())
editor.apply() editor.apply()
activity.finish() activity.finish()
if (setupDone) {
//Reopen of activity so values will be updated //Reopen of activity so values will be updated
val intent = Intent(activity, StundenplanActivity::class.java) val intent = Intent(activity, StundenplanActivity::class.java)
//Remove previous StundenplanActivity from activity stack so when going back later it won't exist twice //Remove previous StundenplanActivity from activity stack so when going back later it won't exist twice
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
startActivity(activity, intent, null) startActivity(activity, intent, null)
}
else {
val intent = Intent(activity, MainActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
startActivity(activity, intent, null)
}
}, },
modifier = Modifier modifier = Modifier
.padding(5.dp) .padding(5.dp)
@@ -492,7 +510,7 @@ fun TimeTableSetupContent(activity: ComponentActivity, loadedLessons: List<Lesso
lessons = lessons + LessonData("", "", "") lessons = lessons + LessonData("", "", "")
} }
while (currentLessonAmount.toInt() < lessons.size) { while (currentLessonAmount.toInt() < lessons.size) {
lessons = lessons.drop(1) lessons = lessons.dropLast(1)
} }
lessons.forEachIndexed { index, lessonData -> lessons.forEachIndexed { index, lessonData ->
@@ -555,6 +573,7 @@ fun TimeTableSetupContent(activity: ComponentActivity, loadedLessons: List<Lesso
colors = inputFieldColors, colors = inputFieldColors,
) )
} }
saveLessonsUsage(activity, lessons, state)
} }
//save an empty list into DataStore currentLessonAmount == 0 //save an empty list into DataStore currentLessonAmount == 0
else { else {
@@ -604,7 +623,6 @@ fun TimeTableSetupContent(activity: ComponentActivity, loadedLessons: List<Lesso
} }
startActivity(activity, intent, null) startActivity(activity, intent, null)
} }
}, },
modifier = Modifier modifier = Modifier
.padding(5.dp) .padding(5.dp)

View File

@@ -1,5 +1,9 @@
package com.schoolapp.cleverclass package com.schoolapp.cleverclass
import android.app.Activity
import android.content.Context
import android.content.Intent
import androidx.activity.ComponentActivity
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
@@ -17,6 +21,10 @@ import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.File
const val NO_INTERNET_CONNECTION_CODE = -1 const val NO_INTERNET_CONNECTION_CODE = -1
@@ -64,3 +72,46 @@ fun StaticLoadingScreen(){
} }
} }
} }
fun deleteAllData(activity: ComponentActivity){
val sharedPrefs = listOf("Settings", "DSBmobile", "gradeAverages", "TimeTable")
for (prefName in sharedPrefs) {
val sharedPreferences = activity.getSharedPreferences(prefName, Context.MODE_PRIVATE)
val editor = sharedPreferences.edit()
editor.clear()
editor.apply()
}
clearFolder(activity.filesDir)
clearFolder(activity.cacheDir)
CoroutineScope(Dispatchers.Main).launch {
restartApp(activity)
}
}
fun clearFolder(directory: File) {
if (directory.exists()) {
val files = directory.listFiles()
if (files != null) {
for (file in files) {
if (file.isDirectory) {
clearFolder(file)
}
file.delete()
}
}
}
}
fun restartApp(context: Context) {
val packageManager = context.packageManager
val intent = packageManager.getLaunchIntentForPackage(context.packageName)
intent?.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
intent?.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(intent)
if (context is Activity) {
context.finish()
}
Runtime.getRuntime().exit(0)
}

View File

@@ -8,9 +8,9 @@ val Black80 = Color(0xFF333333)
val Black70 = Color(0xFF4B4B4B) val Black70 = Color(0xFF4B4B4B)
val White100 = Color(0xFFFFFFFF) val White100 = Color(0xFFFFFFFF)
val White90 = Color(0xFFEBEBEB) val White90 = Color(0xFFFAFAFA)
val White80 = Color(0xFFD3D3D3) val White80 = Color(0xFFD3D3D3)
val White70 = Color(0xFFBBBBBB) val White70 = Color(0xFFAFAFAF)
val TextOnColouredButton = Color(0xFF121212) val TextOnColouredButton = Color(0xFF121212)