Update DSBmobile

This commit is contained in:
BuildTools
2024-04-21 20:24:22 +02:00
parent 2e1f335a47
commit cd9e26fbe5
8 changed files with 277 additions and 23 deletions

View File

@@ -61,14 +61,11 @@ dependencies {
implementation("androidx.datastore:datastore-preferences:1.0.0") implementation("androidx.datastore:datastore-preferences:1.0.0")
implementation("com.google.code.gson:gson:2.9.0") implementation("com.google.code.gson:gson:2.9.0")
implementation(platform("androidx.compose:compose-bom:2023.03.00")) implementation(platform("androidx.compose:compose-bom:2023.03.00"))
implementation(platform("androidx.compose:compose-bom:2023.03.00"))
testImplementation("junit:junit:4.13.2") testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5") androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
androidTestImplementation("androidx.compose.ui:ui-test-junit4") androidTestImplementation("androidx.compose.ui:ui-test-junit4")
androidTestImplementation(platform("androidx.compose:compose-bom:2023.03.00")) androidTestImplementation(platform("androidx.compose:compose-bom:2023.03.00"))
androidTestImplementation(platform("androidx.compose:compose-bom:2023.03.00"))
androidTestImplementation(platform("androidx.compose:compose-bom:2023.03.00"))
debugImplementation("androidx.compose.ui:ui-tooling") debugImplementation("androidx.compose.ui:ui-tooling")
debugImplementation("androidx.compose.ui:ui-test-manifest") debugImplementation("androidx.compose.ui:ui-test-manifest")
} }

View File

@@ -3,6 +3,7 @@
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application <application
android:allowBackup="true" android:allowBackup="true"
@@ -14,6 +15,11 @@
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/Theme.CleverClass" android:theme="@style/Theme.CleverClass"
tools:targetApi="31"> tools:targetApi="31">
<activity
android:name=".DSBDayViewActivity"
android:exported="false"
android:label="@string/title_activity_dsbday_view"
android:theme="@style/Theme.CleverClass" />
<activity <activity
android:name=".MebisActivity" android:name=".MebisActivity"
android:exported="false" android:exported="false"

View File

@@ -1,10 +1,14 @@
package com.schoolapp.cleverclass package com.schoolapp.cleverclass
import android.content.Context
import android.content.Intent
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import android.os.Bundle import android.os.Bundle
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
@@ -15,6 +19,9 @@ 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.material.icons.filled.Refresh
import androidx.compose.material3.CircularProgressIndicator
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
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
@@ -24,25 +31,29 @@ 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.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.Modifier
import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.schoolapp.cleverclass.ui.theme.CleverClassTheme import com.schoolapp.cleverclass.ui.theme.CleverClassTheme
import com.schoolapp.cleverclass.ui.theme.MiddleColor
import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.json.JSONObject
import java.io.File import java.io.File
class DSBActivity : ComponentActivity() { class DSBActivity : ComponentActivity() {
@OptIn(DelicateCoroutinesApi::class)
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
GlobalScope.launch(Dispatchers.IO) {
downloadDSB(this@DSBActivity)
}
setContent { setContent {
CleverClassTheme { CleverClassTheme {
Surface( Surface(
@@ -57,9 +68,19 @@ class DSBActivity : ComponentActivity() {
} }
// Content of DSBmobile // Content of DSBmobile
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class, DelicateCoroutinesApi::class)
@Composable @Composable
fun DSBContent(activity: ComponentActivity){ fun DSBContent(activity: ComponentActivity){
var loadingState by remember {
mutableStateOf(1)
}
LaunchedEffect(Unit) {
GlobalScope.launch(Dispatchers.IO) {
loadingState = downloadDSB(activity)
}
}
Column { Column {
TopAppBar( TopAppBar(
colors = TopAppBarDefaults.centerAlignedTopAppBarColors(MaterialTheme.colorScheme.primaryContainer), colors = TopAppBarDefaults.centerAlignedTopAppBarColors(MaterialTheme.colorScheme.primaryContainer),
@@ -78,30 +99,120 @@ fun DSBContent(activity: ComponentActivity){
) )
} }
}, },
actions = {
if(loadingState != 1) {
IconButton(
onClick = {
loadingState = 1
GlobalScope.launch(Dispatchers.IO) {
loadingState = downloadDSB(activity)
}
}
) {
Icon(
imageVector = Icons.Filled.Refresh,
contentDescription = null,
modifier = Modifier.size(28.dp),
tint = MaterialTheme.colorScheme.onPrimaryContainer
)
}
}
},
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) )
Column(modifier = Modifier.verticalScroll(rememberScrollState())) { when (loadingState) {
1 -> {
DSBLoading()
}
-1 -> {
DSBNoInternet()
}
else -> {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.verticalScroll(rememberScrollState())
.fillMaxWidth()
) {
Spacer(modifier = Modifier.height(32.dp))
val mainFolder = File(activity.filesDir, "dataDSB") val mainFolder = File(activity.filesDir, "dataDSB")
mainFolder.listFiles()?.forEach { folder -> mainFolder.listFiles()?.forEach { folder ->
DayPrefab(folder = folder) DayPrefab(folder, activity)
Spacer(modifier = Modifier.height(48.dp)) Spacer(modifier = Modifier.height(32.dp))
Divider()
Spacer(modifier = Modifier.height(32.dp))
}
}
} }
} }
} }
} }
@Composable @Composable
fun DayPrefab(folder: File){ fun DSBLoading(){
val imageFiles = folder.listFiles { file -> file.extension == "jpg" }?.toList() Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
){
CircularProgressIndicator()
}
}
Column { @Composable
imageFiles?.forEach { fun DSBNoInternet(){
val imageBitmap = BitmapFactory.decodeFile(it.absolutePath) Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
){
Text(
text = "Keine Internetverbindung",
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onBackground
)
}
}
@Composable
fun DayPrefab(folder: File, activity: Context){
Box(
contentAlignment = Alignment.Center,
modifier = Modifier
.fillMaxWidth()
.height(300.dp)
.clickable {
val intent = Intent(activity, DSBDayViewActivity::class.java).apply {
putExtra(DSBDayViewActivity.FOLDER_KEY, folder.absolutePath)
}
activity.startActivity(intent)
}
) {
val information = JSONObject(File(folder, "info.json").readText())
val previewImageBitmap = BitmapFactory.decodeFile(File(folder, "0.jpg").absolutePath)
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text(
text = "${information.get("FormatInfo")} - ${information.get("PlanInfo").toString().removeSuffix(".pdf")}",
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onBackground
)
Image(bitmap = imageBitmap.asImageBitmap(), contentDescription = null)
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
Text(
text = information.get("Date").toString(),
style = MaterialTheme.typography.bodySmall,
color = MiddleColor
)
Spacer(modifier = Modifier.height(8.dp))
Image(
bitmap = previewImageBitmap.asImageBitmap(),
contentDescription = null
)
} }
} }
} }

View File

@@ -0,0 +1,107 @@
package com.schoolapp.cleverclass
import android.graphics.BitmapFactory
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
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.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.unit.dp
import com.schoolapp.cleverclass.ui.theme.CleverClassTheme
import org.json.JSONObject
import java.io.File
private lateinit var folder : File
private lateinit var information : JSONObject
class DSBDayViewActivity : ComponentActivity() {
companion object{
const val FOLDER_KEY = "folder_key"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
folder = File(intent.getStringExtra(FOLDER_KEY) ?: "")
information = JSONObject(File(folder, "info.json").readText())
setContent {
CleverClassTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
DSBDayViewContent(activity = this)
}
}
}
}
}
// Content of DSBDayView
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun DSBDayViewContent(activity: ComponentActivity){
Column{
TopAppBar(
colors = TopAppBarDefaults.centerAlignedTopAppBarColors(MaterialTheme.colorScheme.primaryContainer),
title = {
Text(
text = information.get("PlanInfo").toString(),
style = MaterialTheme.typography.headlineSmall,
color = MaterialTheme.colorScheme.onPrimaryContainer
)},
navigationIcon = {
IconButton(onClick = { activity.finish() }) {
Icon(
imageVector = Icons.Filled.ArrowBack,
contentDescription = null,
modifier = Modifier.size(28.dp),
tint = MaterialTheme.colorScheme.onPrimaryContainer
)
}
},
modifier = Modifier.fillMaxWidth()
)
val imageFiles = folder.listFiles { file -> file.extension == "jpg" }?.toList()
Column(
modifier = Modifier
.padding(8.dp)
.verticalScroll(rememberScrollState())
) {
imageFiles?.forEach {
Image(
bitmap = BitmapFactory.decodeFile(it.absolutePath).asImageBitmap(),
contentDescription = null,
contentScale = ContentScale.FillWidth,
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(8.dp))
}
}
}
}

View File

@@ -1,6 +1,8 @@
package com.schoolapp.cleverclass package com.schoolapp.cleverclass
import android.content.Context import android.content.Context
import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import android.util.Base64 import android.util.Base64
import android.util.Log import android.util.Log
import org.json.JSONObject import org.json.JSONObject
@@ -16,12 +18,17 @@ import java.time.LocalDateTime
import java.util.UUID import java.util.UUID
suspend fun downloadDSB(context: Context){ suspend fun downloadDSB(context: Context): Int{
if(!isInternetAvailable(context))
return -1
val mainDir = createDataFolder(context) val mainDir = createDataFolder(context)
val jsonResponse = downloadDataTask() val jsonResponse = downloadDataTask()
downloadImagesTask(jsonResponse, mainDir) downloadImagesTask(jsonResponse, mainDir)
return 0
} }
private fun downloadDataTask() : String { private fun downloadDataTask() : String {
@@ -123,6 +130,7 @@ private fun downloadImagesTask(jsonResponse: String, mainDir : File){
val day = File(mainDir, dayID.toString()) val day = File(mainDir, dayID.toString())
day.mkdir() day.mkdir()
createDayInformationJson(day, jsonDayObject)
val jsonPagesObject = jsonDayObject.getJSONArray("Childs") val jsonPagesObject = jsonDayObject.getJSONArray("Childs")
@@ -136,6 +144,20 @@ private fun downloadImagesTask(jsonResponse: String, mainDir : File){
} }
} }
private fun createDayInformationJson(folder: File, jsonDayObject: JSONObject){
val infoFile = File(folder, "info.json")
val date = jsonDayObject.get("Date")
val formatInfo = jsonDayObject.get("Title")
val planInfo = jsonDayObject.getJSONArray("Childs").getJSONObject(0).get("Title")
val infoJson = JSONObject()
infoJson.put("Date", date)
infoJson.put("FormatInfo", formatInfo)
infoJson.put("PlanInfo", planInfo)
infoFile.writeText(infoJson.toString())
}
private fun downloadImage(folder: File, url: URL, fileName: String){ private fun downloadImage(folder: File, url: URL, fileName: String){
val file = File(folder, fileName) val file = File(folder, fileName)
@@ -177,3 +199,10 @@ private fun clearFolder(directory: File) {
} }
} }
} }
private fun isInternetAvailable(context: Context): Boolean {
val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val network = connectivityManager.activeNetwork
val networkCapabilities = connectivityManager.getNetworkCapabilities(network)
return networkCapabilities?.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) ?: false
}

View File

@@ -11,6 +11,7 @@ val White90 = Color(0xFFEBEBEB)
val White70 = Color(0xFFD3D3D3) val White70 = Color(0xFFD3D3D3)
val TextOnColouredButton = Color(0xFF121212) val TextOnColouredButton = Color(0xFF121212)
val MiddleColor = Color(0xFF808080)
val dismissLight = Color(0xFF536DFE) val dismissLight = Color(0xFF536DFE)
val dismissDark = Color(0xFF448AFF) val dismissDark = Color(0xFF448AFF)

View File

@@ -22,6 +22,7 @@ private val DarkColorScheme = darkColorScheme(
onPrimaryContainer = White100, onPrimaryContainer = White100,
secondary = dismissDark, secondary = dismissDark,
onBackground = White100, onBackground = White100,
outlineVariant = Black70,
primary = Color(0xFF536DFE) primary = Color(0xFF536DFE)
) )
@@ -31,6 +32,7 @@ private val LightColorScheme = lightColorScheme(
onPrimaryContainer = Black100, onPrimaryContainer = Black100,
secondary = dismissLight, secondary = dismissLight,
onBackground = Black100, onBackground = Black100,
outlineVariant = White70,
primary = Color(0xFF8396FF) primary = Color(0xFF8396FF)
) )

View File

@@ -9,4 +9,5 @@
<string name="dialog_schließen">Schließen</string> <string name="dialog_schließen">Schließen</string>
<string name="title_activity_dsbactivity">DSBActivity</string> <string name="title_activity_dsbactivity">DSBActivity</string>
<string name="title_activity_mebis">MebisActivity</string> <string name="title_activity_mebis">MebisActivity</string>
<string name="title_activity_dsbday_view">DSBDayViewActivity</string>
</resources> </resources>