Update dependencies, AGP and make the app build again

This commit is contained in:
Jannik 2022-12-22 17:26:07 +01:00
parent b76f869ef0
commit 3e52061a20
Signed by: Seil0
GPG Key ID: E8459F3723C52C24
14 changed files with 221 additions and 220 deletions

View File

@ -6,13 +6,13 @@ android {
signingConfigs { signingConfigs {
} }
compileSdkVersion 30 compileSdkVersion 33
buildToolsVersion "30.0.2" buildToolsVersion "30.0.3"
defaultConfig { defaultConfig {
applicationId "org.mosad.seil0.projectlaogai" applicationId "org.mosad.seil0.projectlaogai"
minSdkVersion 23 minSdkVersion 23
targetSdkVersion 30 targetSdkVersion 33
versionCode 6091 // 00.06.091 versionCode 6091 // 00.06.091
versionName "0.6.1-beta2" versionName "0.6.1-beta2"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@ -66,30 +66,30 @@ android {
dependencies { dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs') implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.2' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4'
implementation 'androidx.core:core-ktx:1.3.2' implementation 'androidx.core:core-ktx:1.9.0'
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.1' implementation 'androidx.navigation:navigation-fragment-ktx:2.5.3'
implementation 'androidx.navigation:navigation-ui-ktx:2.3.1' implementation 'androidx.navigation:navigation-ui-ktx:2.5.3'
implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'androidx.appcompat:appcompat:1.5.1'
implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4' implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
implementation 'androidx.security:security-crypto:1.1.0-alpha02' implementation 'androidx.security:security-crypto:1.1.0-alpha04'
implementation "androidx.work:work-runtime-ktx:2.4.0" implementation "androidx.work:work-runtime-ktx:2.7.1"
implementation 'com.google.android.material:material:1.2.1' implementation 'com.google.android.material:material:1.7.0'
implementation 'com.google.code.gson:gson:2.8.6' implementation 'com.google.code.gson:gson:2.10'
implementation 'com.afollestad:aesthetic:1.0.0-beta05' // implementation 'com.afollestad:aesthetic:1.0.0-beta05'
implementation 'com.afollestad.material-dialogs:core:3.3.0' implementation 'com.afollestad.material-dialogs:core:3.3.0'
implementation 'com.afollestad.material-dialogs:color:3.3.0' implementation 'com.afollestad.material-dialogs:color:3.3.0'
implementation 'com.afollestad.material-dialogs:bottomsheets:3.3.0' implementation 'com.afollestad.material-dialogs:bottomsheets:3.3.0'
implementation 'de.psdev.licensesdialog:licensesdialog:2.1.0' implementation 'de.psdev.licensesdialog:licensesdialog:2.1.0'
implementation 'org.apache.commons:commons-lang3:3.11' implementation 'org.apache.commons:commons-lang3:3.11'
implementation 'org.jsoup:jsoup:1.13.1' implementation 'org.jsoup:jsoup:1.15.3'
testImplementation 'org.junit.jupiter:junit-jupiter:5.6.2' testImplementation 'org.junit.jupiter:junit-jupiter:5.8.2'
androidTestImplementation 'androidx.test:core:1.3.0' androidTestImplementation 'androidx.test:core:1.5.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.2' androidTestImplementation 'androidx.test.ext:junit:1.1.4'
} }
static def buildTime() { static def buildTime() {

View File

@ -1,55 +1,56 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.mosad.seil0.projectlaogai"> package="org.mosad.seil0.projectlaogai">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.NFC" /> <uses-permission android:name="android.permission.NFC" />
<application <application
android:allowBackup="true" android:allowBackup="true"
android:fullBackupContent="@xml/backup_descriptor" android:fullBackupContent="@xml/backup_descriptor"
android:icon="@mipmap/ic_laogai_icon" android:icon="@mipmap/ic_laogai_icon"
android:label="@string/app_name" android:label="@string/app_name"
android:roundIcon="@mipmap/ic_laogai_icon" android:roundIcon="@mipmap/ic_laogai_icon"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/AppTheme.Light"> android:theme="@style/AppTheme.Light">
<activity <activity
android:name=".SplashActivity" android:name=".SplashActivity"
android:label="@string/app_name" android:screenOrientation="portrait"
android:theme="@style/SplashTheme" android:theme="@style/SplashTheme"
android:screenOrientation="portrait"> android:exported="true">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN"/> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER"/> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
<meta-data android:name="android.app.shortcuts" <meta-data
android:resource="@xml/shortcuts" /> android:name="android.app.shortcuts"
android:resource="@xml/shortcuts" />
</activity> </activity>
<activity <activity
android:name=".OnboardingActivity" android:name=".OnboardingActivity"
android:label="@string/app_name" android:launchMode="singleTop"
android:theme="@style/AppTheme.Light" android:screenOrientation="portrait"
android:screenOrientation="portrait" android:theme="@style/AppTheme.Light" />
android:launchMode="singleTop">
</activity>
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:label="@string/app_name" android:exported="true"
android:theme="@style/AppTheme.Light" android:launchMode="singleTop"
android:screenOrientation="portrait" android:screenOrientation="portrait"
android:launchMode="singleTop"> android:theme="@style/AppTheme.Light">
<!-- nfc stuff --> <!-- nfc stuff -->
<intent-filter> <intent-filter>
<action android:name="android.nfc.action.TECH_DISCOVERED"/> <action android:name="android.nfc.action.TECH_DISCOVERED" />
</intent-filter> </intent-filter>
<meta-data android:name="android.nfc.action.TECH_DISCOVERED" <meta-data
android:resource="@xml/nfc_tech_filter" /> android:name="android.nfc.action.TECH_DISCOVERED"
android:resource="@xml/nfc_tech_filter" />
</activity> </activity>
</application> </application>

View File

@ -34,14 +34,15 @@ import android.util.Log
import android.util.TypedValue import android.util.TypedValue
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import androidx.activity.addCallback
import androidx.appcompat.app.ActionBarDrawerToggle import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.GravityCompat import androidx.core.view.GravityCompat
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentTransaction import androidx.fragment.app.FragmentTransaction
import androidx.fragment.app.commit import androidx.fragment.app.commit
import com.afollestad.aesthetic.Aesthetic //import com.afollestad.aesthetic.Aesthetic
import com.afollestad.aesthetic.NavigationViewMode //import com.afollestad.aesthetic.NavigationViewMode
import com.google.android.material.navigation.NavigationView import com.google.android.material.navigation.NavigationView
import org.mosad.seil0.projectlaogai.controller.NFCMensaCard import org.mosad.seil0.projectlaogai.controller.NFCMensaCard
import org.mosad.seil0.projectlaogai.controller.cache.CacheController import org.mosad.seil0.projectlaogai.controller.cache.CacheController
@ -67,7 +68,7 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
private var useNFC = false private var useNFC = false
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
Aesthetic.attach(this) // Aesthetic.attach(this)
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater) binding = ActivityMainBinding.inflate(layoutInflater)
@ -100,6 +101,12 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
supportFragmentManager.commit { supportFragmentManager.commit {
replace(R.id.fragment_container, activeFragment, activeFragment.javaClass.simpleName) replace(R.id.fragment_container, activeFragment, activeFragment.javaClass.simpleName)
} }
onBackPressedDispatcher.addCallback {
if (binding.drawerLayout.isDrawerOpen(GravityCompat.START)) {
binding.drawerLayout.closeDrawer(GravityCompat.START)
}
}
} }
override fun onNewIntent(intent: Intent) { override fun onNewIntent(intent: Intent) {
@ -112,7 +119,7 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
Aesthetic.resume(this) // Aesthetic.resume(this)
if(useNFC) if(useNFC)
adapter.enableForegroundDispatch(this, pendingIntent, intentFiltersArray, techListsArray) adapter.enableForegroundDispatch(this, pendingIntent, intentFiltersArray, techListsArray)
@ -120,20 +127,11 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
override fun onPause() { override fun onPause() {
super.onPause() super.onPause()
Aesthetic.pause(this) // Aesthetic.pause(this)
if(useNFC) if(useNFC)
adapter.disableForegroundDispatch(this) adapter.disableForegroundDispatch(this)
} }
override fun onBackPressed() {
if (binding.drawerLayout.isDrawerOpen(GravityCompat.START)) {
binding.drawerLayout.closeDrawer(GravityCompat.START)
} else {
// TODO only call on double tap
super.onBackPressed()
}
}
override fun onCreateOptionsMenu(menu: Menu): Boolean { override fun onCreateOptionsMenu(menu: Menu): Boolean {
// Inflate the menu; this adds items to the action bar if it is present. // Inflate the menu; this adds items to the action bar if it is present.
menuInflater.inflate(R.menu.main, menu) menuInflater.inflate(R.menu.main, menu)
@ -186,25 +184,25 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
private fun initAesthetic() { private fun initAesthetic() {
// If we haven't set any defaults, do that now // If we haven't set any defaults, do that now
if (Aesthetic.isFirstTime) { // if (Aesthetic.isFirstTime) {
// set the default theme at the first app start // // set the default theme at the first app start
Aesthetic.config { // Aesthetic.config {
activityTheme(R.style.AppTheme_Light) // activityTheme(R.style.AppTheme_Light)
apply() // apply()
} // }
// // TODO needs to be shown on first start
// show the onboarding activity // // show the onboarding activity
startActivity(Intent(this, OnboardingActivity::class.java)) // startActivity(Intent(this, OnboardingActivity::class.java))
finish() // finish()
} // }
//
Aesthetic.config { // Aesthetic.config {
colorPrimary(Preferences.colorPrimary) // colorPrimary(Preferences.colorPrimary)
colorPrimaryDark(Preferences.colorPrimary) // colorPrimaryDark(Preferences.colorPrimary)
colorAccent(Preferences.colorAccent) // colorAccent(Preferences.colorAccent)
navigationViewMode(NavigationViewMode.SELECTED_ACCENT) // navigationViewMode(NavigationViewMode.SELECTED_ACCENT)
apply() // apply()
} // }
// set theme color values // set theme color values
val out = TypedValue() val out = TypedValue()

View File

@ -31,6 +31,7 @@ import android.widget.LinearLayout
import android.widget.TextView import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.text.HtmlCompat import androidx.core.text.HtmlCompat
import androidx.lifecycle.lifecycleScope
import androidx.viewpager.widget.ViewPager import androidx.viewpager.widget.ViewPager
import kotlinx.coroutines.* import kotlinx.coroutines.*
import org.mosad.seil0.projectlaogai.controller.cache.CacheController import org.mosad.seil0.projectlaogai.controller.cache.CacheController
@ -94,7 +95,7 @@ class OnboardingActivity : AppCompatActivity() {
val loadingDialog = LoadingDialog(context) val loadingDialog = LoadingDialog(context)
loadingDialog.show() loadingDialog.show()
GlobalScope.launch(Dispatchers.Default) { lifecycleScope.launch(Dispatchers.Default) {
Preferences.saveCourse(context, CacheController.coursesList[selectedIndex]) // save the course Preferences.saveCourse(context, CacheController.coursesList[selectedIndex]) // save the course
// update current & next weeks timetable // update current & next weeks timetable

View File

@ -160,7 +160,8 @@ class QISPOSParser(val context: Context) {
// grades root document and url // grades root document and url
val rootHtml =Jsoup.parse(res.body()) val rootHtml =Jsoup.parse(res.body())
val gradesRootLink = rootHtml.select("li.menueListStyle > a.auflistung").last().attr("abs:href") val gradesRootLink =
rootHtml.select("li.menueListStyle > a.auflistung").last()!!.attr("abs:href")
// parse grades url // parse grades url
val gradesHtml = Jsoup.connect(gradesRootLink) val gradesHtml = Jsoup.connect(gradesRootLink)
@ -179,7 +180,7 @@ class QISPOSParser(val context: Context) {
.referrer("https://notenverwaltung.hs-offenburg.de/qispos/rds?state=user&type=0") .referrer("https://notenverwaltung.hs-offenburg.de/qispos/rds?state=user&type=0")
.get() .get()
val gradesListLink = gradesNextHtml.selectFirst("li.treelist > ul > li").selectFirst("a").attr("abs:href") val gradesListLink = gradesNextHtml.selectFirst("li.treelist > ul > li")!!.selectFirst("a")!!.attr("abs:href")
// get the grades list // get the grades list
val gradesListHtml = Jsoup.connect(gradesListLink) val gradesListHtml = Jsoup.connect(gradesListLink)

View File

@ -84,7 +84,7 @@ class TCoRAPIController {
fun getSubjectListAsync(courseName: String, week: Int): Deferred<ArrayList<String>> { fun getSubjectListAsync(courseName: String, week: Int): Deferred<ArrayList<String>> {
val url = URL("$tcorBaseURL/subjectList?course=$courseName&week=$week") val url = URL("$tcorBaseURL/subjectList?course=$courseName&week=$week")
return GlobalScope.async { return CoroutineScope(Dispatchers.IO).async {
Gson().fromJson(url.readText(), ArrayList<String>()::class.java) Gson().fromJson(url.readText(), ArrayList<String>()::class.java)
} }
} }

View File

@ -64,7 +64,7 @@ class CacheController(private val context: Context) {
// if a) it's monday and the last cache update was on sunday or b) the cache is older than 24hr, update blocking // if a) it's monday and the last cache update was on sunday or b) the cache is older than 24hr, update blocking
if ((currentDay == Calendar.MONDAY && cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) || (currentTime - mensaCacheTime) > 86400) { if ((currentDay == Calendar.MONDAY && cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) || (currentTime - mensaCacheTime) > 86400) {
Log.i(className, "Update mensa blocking") Log.i(className, "Update mensa blocking")
GlobalScope.launch(Dispatchers.Default) { updateMensaMenu(context).join() } CoroutineScope(Dispatchers.Default).launch { updateMensaMenu(context).join() }
} }
// check if we need to update the timetable before displaying it // check if we need to update the timetable before displaying it
@ -74,7 +74,7 @@ class CacheController(private val context: Context) {
if ((currentDay == Calendar.MONDAY && cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) || (currentTime - timetableCacheTime) > 86400) { if ((currentDay == Calendar.MONDAY && cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) || (currentTime - timetableCacheTime) > 86400) {
Log.i(className, "Updating timetable after sunday!") Log.i(className, "Updating timetable after sunday!")
GlobalScope.launch(Dispatchers.Default) { CoroutineScope(Dispatchers.Default).launch {
val threads = listOf( val threads = listOf(
updateTimetable(Preferences.course.courseName, 0, context), updateTimetable(Preferences.course.courseName, 0, context),
updateTimetable(Preferences.course.courseName, 1, context) updateTimetable(Preferences.course.courseName, 1, context)
@ -110,7 +110,7 @@ class CacheController(private val context: Context) {
val file = File(context.filesDir, "courses.json") val file = File(context.filesDir, "courses.json")
var courseListUp = CoursesList() var courseListUp = CoursesList()
return GlobalScope.launch(Dispatchers.IO) { return CoroutineScope(Dispatchers.IO).launch {
try { try {
courseListUp = TCoRAPIController.getCourseListNEW() courseListUp = TCoRAPIController.getCourseListNEW()
} catch (ex: Exception) { } catch (ex: Exception) {
@ -133,7 +133,7 @@ class CacheController(private val context: Context) {
fun updateMensaMenu(context: Context): Job { fun updateMensaMenu(context: Context): Job {
val file = File(context.filesDir, "mensa.json") val file = File(context.filesDir, "mensa.json")
return GlobalScope.launch(Dispatchers.IO) { return CoroutineScope(Dispatchers.IO).launch {
try { try {
mensaMenu = TCoRAPIController.getMensaMenu() mensaMenu = TCoRAPIController.getMensaMenu()
} catch (ex: Exception) { } catch (ex: Exception) {
@ -157,7 +157,7 @@ class CacheController(private val context: Context) {
var timetable = TimetableWeek() var timetable = TimetableWeek()
// try to update timetable from tcor, async // try to update timetable from tcor, async
return GlobalScope.launch(Dispatchers.IO) { return CoroutineScope(Dispatchers.IO).launch {
try { try {
timetable = TCoRAPIController.getTimetable(courseName, week) timetable = TCoRAPIController.getTimetable(courseName, week)
} catch (ex: Exception) { } catch (ex: Exception) {
@ -184,7 +184,7 @@ class CacheController(private val context: Context) {
fun updateAdditionalLessons(context: Context): Job { fun updateAdditionalLessons(context: Context): Job {
val fileLessons = File(context.filesDir, "additional_lessons.json") val fileLessons = File(context.filesDir, "additional_lessons.json")
return GlobalScope.launch(Dispatchers.IO) { return CoroutineScope(Dispatchers.IO).launch {
TimetableController.subjectMap.forEach { (courseName, subjects) -> TimetableController.subjectMap.forEach { (courseName, subjects) ->
// update all subjects for a course // update all subjects for a course
subjects.forEach {subject -> subjects.forEach {subject ->
@ -209,7 +209,7 @@ class CacheController(private val context: Context) {
val file = File(context.filesDir, "grades_encrypted") val file = File(context.filesDir, "grades_encrypted")
val parser = QISPOSParser(context) val parser = QISPOSParser(context)
return GlobalScope.launch(Dispatchers.IO) { return CoroutineScope(Dispatchers.IO).launch {
if (parser.checkQISPOSStatus() == 200) { if (parser.checkQISPOSStatus() == 200) {
// save cache file and update time // save cache file and update time
saveEncrypted(context, file, Gson().toJson(parser.parseGrades())) saveEncrypted(context, file, Gson().toJson(parser.parseGrades()))

View File

@ -24,12 +24,14 @@ package org.mosad.seil0.projectlaogai.fragments
import android.graphics.Rect import android.graphics.Rect
import android.os.Bundle import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.TextView import android.widget.TextView
import androidx.core.content.res.ResourcesCompat import androidx.core.content.res.ResourcesCompat
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.* import kotlinx.coroutines.*
import org.mosad.seil0.projectlaogai.R import org.mosad.seil0.projectlaogai.R
import org.mosad.seil0.projectlaogai.controller.QISPOSParser import org.mosad.seil0.projectlaogai.controller.QISPOSParser
@ -62,16 +64,16 @@ class GradesFragment : Fragment() {
binding.refreshLayoutGrades.setProgressBackgroundColorSchemeColor(Preferences.themeSecondary) binding.refreshLayoutGrades.setProgressBackgroundColorSchemeColor(Preferences.themeSecondary)
initActions() initActions()
parser = QISPOSParser(context!!)// init the parser parser = QISPOSParser(requireContext())// init the parser
if (checkCredentials()) { if (checkCredentials()) {
GlobalScope.launch(Dispatchers.Default) { lifecycleScope.launch(Dispatchers.Default) {
// if the cache is older than 24hr, update blocking // if the cache is older than 24hr, update blocking
val currentTime = System.currentTimeMillis() / 1000 val currentTime = System.currentTimeMillis() / 1000
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
if ((currentTime - Preferences.gradesCacheTime) > 86400 && checkQisposStatus()) { if ((currentTime - Preferences.gradesCacheTime) > 86400 && checkQisposStatus()) {
binding.refreshLayoutGrades.isRefreshing = true binding.refreshLayoutGrades.isRefreshing = true
CacheController.updateGrades(context!!).join() CacheController.updateGrades(requireContext()).join()
} }
} }
@ -83,13 +85,13 @@ class GradesFragment : Fragment() {
/** /**
* initialize the actions * initialize the actions
*/ */
private fun initActions() = GlobalScope.launch(Dispatchers.Default) { private fun initActions() = lifecycleScope.launch(Dispatchers.Default) {
binding.refreshLayoutGrades.setOnRefreshListener { binding.refreshLayoutGrades.setOnRefreshListener {
binding.linLayoutGrades.removeAllViews() // clear layout binding.linLayoutGrades.removeAllViews() // clear layout
// TODO add loading textView // TODO add loading textView
GlobalScope.launch(Dispatchers.Default) { lifecycleScope.launch(Dispatchers.Default) {
CacheController.updateGrades(context!!).join() CacheController.updateGrades(requireContext()).join()
addGrades() addGrades()
} }
} }
@ -99,12 +101,12 @@ class GradesFragment : Fragment() {
* check if the credentials are set, if not show a login dialog * check if the credentials are set, if not show a login dialog
*/ */
private fun checkCredentials(): Boolean { private fun checkCredentials(): Boolean {
val credentials = EncryptedPreferences.readCredentials(context!!) val credentials = EncryptedPreferences.readCredentials(requireContext())
var credentialsPresent = false var credentialsPresent = false
// if there is no password set, show the login dialog // if there is no password set, show the login dialog
if (credentials.first.isEmpty() || credentials.second.isEmpty()) { if (credentials.first.isEmpty() || credentials.second.isEmpty()) {
LoginDialog(this.context!!) LoginDialog(this.requireContext())
.positiveButton { .positiveButton {
EncryptedPreferences.saveCredentials(email, password, context) EncryptedPreferences.saveCredentials(email, password, context)
addGrades() addGrades()
@ -153,9 +155,9 @@ class GradesFragment : Fragment() {
* add the grades to the layout, async * add the grades to the layout, async
* TODO this is slow as hell * TODO this is slow as hell
*/ */
private fun addGrades() = GlobalScope.launch(Dispatchers.Default) { private fun addGrades() = lifecycleScope.launch(Dispatchers.Default) {
val addGradesTime = measureTimeMillis { val addGradesTime = measureTimeMillis {
val grades = CacheController(context!!).readGrades() val grades = CacheController(requireContext()).readGrades()
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
binding.linLayoutGrades.removeAllViews() // clear layout binding.linLayoutGrades.removeAllViews() // clear layout
@ -165,7 +167,7 @@ class GradesFragment : Fragment() {
// for each semester add a new card // for each semester add a new card
grades.forEach { semester -> grades.forEach { semester ->
val usedSubjects = ArrayList<String>() val usedSubjects = ArrayList<String>()
val semesterCard = DayCardView(context!!) val semesterCard = DayCardView(requireContext())
semesterCard.setDayHeading(semester.key) semesterCard.setDayHeading(semester.key)
// for each subject add a new linLayout // for each subject add a new linLayout
@ -220,7 +222,7 @@ class GradesFragment : Fragment() {
} }
} }
println("added grades in $addGradesTime ms") Log.i(javaClass.name, "added grades in $addGradesTime ms")
} }
} }

View File

@ -30,6 +30,7 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.TextView import android.widget.TextView
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.* import kotlinx.coroutines.*
import org.mosad.seil0.projectlaogai.R import org.mosad.seil0.projectlaogai.R
import org.mosad.seil0.projectlaogai.controller.cache.CacheController.Companion.mensaMenu import org.mosad.seil0.projectlaogai.controller.cache.CacheController.Companion.mensaMenu
@ -68,22 +69,22 @@ class HomeFragment : Fragment() {
/** /**
* add the current mensa meal to the home screens * add the current mensa meal to the home screens
*/ */
private fun addMensaMenu() = GlobalScope.launch(Dispatchers.Default) { private fun addMensaMenu() = lifecycleScope.launch(Dispatchers.Default) {
var dayMeals: ArrayList<Meal> var dayMeals: ArrayList<Meal>
val cal = Calendar.getInstance() val cal = Calendar.getInstance()
val mensaCardView = DayCardView(context!!) val mensaCardView = DayCardView(requireContext())
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
if (isAdded) { if (isAdded) {
if (cal.get(Calendar.HOUR_OF_DAY) < 15) { if (cal.get(Calendar.HOUR_OF_DAY) < 15) {
dayMeals = mensaMenu.currentWeek.days[NotRetardedCalendar.getDayOfWeekIndex()].meals dayMeals = mensaMenu.currentWeek.days[NotRetardedCalendar.getDayOfWeekIndex()].meals
mensaCardView.setDayHeading(activity!!.resources.getString(R.string.today_date, formatter.format(cal.time))) mensaCardView.setDayHeading(getString(R.string.today_date, formatter.format(cal.time)))
} else { } else {
dayMeals = mensaMenu.currentWeek.days[NotRetardedCalendar.getTomorrowWeekIndex()].meals dayMeals = mensaMenu.currentWeek.days[NotRetardedCalendar.getTomorrowWeekIndex()].meals
cal.add(Calendar.DATE, 1) cal.add(Calendar.DATE, 1)
mensaCardView.setDayHeading(activity!!.resources.getString(R.string.tomorrow_date, formatter.format(cal.time))) mensaCardView.setDayHeading(getString(R.string.tomorrow_date, formatter.format(cal.time)))
} }
if (dayMeals.size >= 2) { if (dayMeals.size >= 2) {
@ -118,20 +119,15 @@ class HomeFragment : Fragment() {
/** /**
* add the current timetable to the home screen * add the current timetable to the home screen
*/ */
private fun addTimeTable() = GlobalScope.launch(Dispatchers.Default) { private fun addTimeTable() = lifecycleScope.launch(Dispatchers.Main) {
if (isAdded && TimetableController.timetable.isNotEmpty()) {
withContext(Dispatchers.Main) { try {
val dayCardView = findNextDay(NotRetardedCalendar.getDayOfWeekIndex())
if (isAdded && TimetableController.timetable.isNotEmpty()) { binding.linLayoutHome.addView(dayCardView)
try { } catch (ex: Exception) {
val dayCardView = findNextDay(NotRetardedCalendar.getDayOfWeekIndex()) Log.e(className, "could not load timetable", ex) // TODO send feedback
binding.linLayoutHome.addView(dayCardView)
} catch (ex: Exception) {
Log.e(className, "could not load timetable", ex) // TODO send feedback
}
} }
} }
} }
/** /**
@ -142,7 +138,7 @@ class HomeFragment : Fragment() {
* @return a DayCardView with all lessons added * @return a DayCardView with all lessons added
*/ */
private fun findNextDay(startDayIndex: Int): DayCardView { private fun findNextDay(startDayIndex: Int): DayCardView {
val dayCardView = DayCardView(context!!) val dayCardView = DayCardView(requireContext())
var dayTimetable: TimetableDay? = null var dayTimetable: TimetableDay? = null
var dayIndexSearch = startDayIndex var dayIndexSearch = startDayIndex
var weekIndexSearch = 0 var weekIndexSearch = 0

View File

@ -27,8 +27,8 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import org.mosad.seil0.projectlaogai.R import org.mosad.seil0.projectlaogai.R
@ -62,7 +62,7 @@ class MensaFragment : Fragment() {
initActions() // init actions initActions() // init actions
GlobalScope.launch(Dispatchers.Default) { lifecycleScope.launch(Dispatchers.Default) {
val dayCurrent = if(NotRetardedCalendar.getDayOfWeekIndex() == 6) 0 else NotRetardedCalendar.getDayOfWeekIndex() val dayCurrent = if(NotRetardedCalendar.getDayOfWeekIndex() == 6) 0 else NotRetardedCalendar.getDayOfWeekIndex()
// add the current and next week // add the current and next week
@ -71,7 +71,7 @@ class MensaFragment : Fragment() {
// show a info if there are no more menus // show a info if there are no more menus
if (binding.linLayoutMensa.childCount == 0) { if (binding.linLayoutMensa.childCount == 0) {
val txtViewInfo = TextViewInfo(context!!).set { val txtViewInfo = TextViewInfo(requireContext()).set {
txt = resources.getString(R.string.no_more_meals) txt = resources.getString(R.string.no_more_meals)
} }
withContext(Dispatchers.Main) { binding.linLayoutMensa.addView(txtViewInfo) } withContext(Dispatchers.Main) { binding.linLayoutMensa.addView(txtViewInfo) }
@ -84,13 +84,13 @@ class MensaFragment : Fragment() {
* @param menusWeek menu of type MensaWeek you want to add * @param menusWeek menu of type MensaWeek you want to add
* @param dayStart the first day of the week to add * @param dayStart the first day of the week to add
*/ */
private fun addWeek(menusWeek: MensaWeek, dayStart: Int) = GlobalScope.launch(Dispatchers.Default) { private fun addWeek(menusWeek: MensaWeek, dayStart: Int) = lifecycleScope.launch(Dispatchers.Default) {
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
// only add the days dayStart to Fri since the mensa is closed on Sat/Sun // only add the days dayStart to Fri since the mensa is closed on Sat/Sun
for (dayIndex in dayStart..4) { for (dayIndex in dayStart..4) {
var helpMeal = MealLinearLayout(context) var helpMeal = MealLinearLayout(context)
val dayCardView = DayCardView(context!!) val dayCardView = DayCardView(requireContext())
if(menusWeek.days[dayIndex].meals.isNotEmpty()) if(menusWeek.days[dayIndex].meals.isNotEmpty())
dayCardView.setDayHeading(menusWeek.days[dayIndex].meals[0].day) dayCardView.setDayHeading(menusWeek.days[dayIndex].meals[0].day)
@ -127,8 +127,8 @@ class MensaFragment : Fragment() {
/** /**
* refresh the mensa cache and update the mensa screen * refresh the mensa cache and update the mensa screen
*/ */
private fun updateMensaScreen() = GlobalScope.launch(Dispatchers.Default) { private fun updateMensaScreen() = lifecycleScope.launch(Dispatchers.Default) {
CacheController.updateMensaMenu(context!!).join() // blocking since we want the new data CacheController.updateMensaMenu(requireContext()).join() // blocking since we want the new data
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
// remove all menus from the layout // remove all menus from the layout
@ -145,7 +145,7 @@ class MensaFragment : Fragment() {
// show a info if there are no more menus // show a info if there are no more menus
if (binding.linLayoutMensa.childCount == 0) { if (binding.linLayoutMensa.childCount == 0) {
val txtViewInfo = TextViewInfo(context!!).set { val txtViewInfo = TextViewInfo(requireContext()).set {
txt = resources.getString(R.string.no_more_meals) txt = resources.getString(R.string.no_more_meals)
} }
binding.linLayoutMensa.addView(txtViewInfo) binding.linLayoutMensa.addView(txtViewInfo)

View File

@ -22,21 +22,24 @@
package org.mosad.seil0.projectlaogai.fragments package org.mosad.seil0.projectlaogai.fragments
//import com.afollestad.aesthetic.Aesthetic
import android.os.Bundle import android.os.Bundle
import android.util.TypedValue import android.util.TypedValue
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import com.afollestad.aesthetic.Aesthetic import androidx.lifecycle.lifecycleScope
import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.WhichButton import com.afollestad.materialdialogs.WhichButton
import com.afollestad.materialdialogs.actions.getActionButton import com.afollestad.materialdialogs.actions.getActionButton
import com.afollestad.materialdialogs.color.colorChooser
import com.afollestad.materialdialogs.list.listItemsMultiChoice import com.afollestad.materialdialogs.list.listItemsMultiChoice
import com.afollestad.materialdialogs.list.listItemsSingleChoice import com.afollestad.materialdialogs.list.listItemsSingleChoice
import de.psdev.licensesdialog.LicensesDialog import de.psdev.licensesdialog.LicensesDialog
import kotlinx.coroutines.* import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.joinAll
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.mosad.seil0.projectlaogai.BuildConfig import org.mosad.seil0.projectlaogai.BuildConfig
import org.mosad.seil0.projectlaogai.R import org.mosad.seil0.projectlaogai.R
import org.mosad.seil0.projectlaogai.controller.GradesController import org.mosad.seil0.projectlaogai.controller.GradesController
@ -50,7 +53,6 @@ import org.mosad.seil0.projectlaogai.uicomponents.dialogs.CourseSelectionDialog
import org.mosad.seil0.projectlaogai.uicomponents.dialogs.LoadingDialog import org.mosad.seil0.projectlaogai.uicomponents.dialogs.LoadingDialog
import org.mosad.seil0.projectlaogai.uicomponents.dialogs.LoginDialog import org.mosad.seil0.projectlaogai.uicomponents.dialogs.LoginDialog
import org.mosad.seil0.projectlaogai.util.DataTypes import org.mosad.seil0.projectlaogai.util.DataTypes
import java.util.*
/** /**
* The settings controller class * The settings controller class
@ -86,20 +88,20 @@ class SettingsFragment : Fragment() {
binding.switchBuffet.isChecked = Preferences.showBuffet // init switch binding.switchBuffet.isChecked = Preferences.showBuffet // init switch
val outValue = TypedValue() val outValue = TypedValue()
activity!!.theme.resolveAttribute(R.attr.themeName, outValue, true) requireActivity().theme.resolveAttribute(R.attr.themeName, outValue, true)
when(outValue.string) { when(outValue.string) {
"light" -> { "light" -> {
binding.switchBuffet.setTextColor(activity!!.resources.getColor(R.color.textPrimaryLight, activity!!.theme)) binding.switchBuffet.setTextColor(requireActivity().resources.getColor(R.color.textPrimaryLight, requireActivity().theme))
selectedTheme = DataTypes.Theme.Light selectedTheme = DataTypes.Theme.Light
selectedTheme.string = resources.getString(R.string.themeLight) selectedTheme.string = resources.getString(R.string.themeLight)
} }
"dark" -> { "dark" -> {
binding.switchBuffet.setTextColor(activity!!.resources.getColor(R.color.textPrimaryDark, activity!!.theme)) binding.switchBuffet.setTextColor(requireActivity().resources.getColor(R.color.textPrimaryDark, requireActivity().theme))
selectedTheme = DataTypes.Theme.Dark selectedTheme = DataTypes.Theme.Dark
selectedTheme.string = resources.getString(R.string.themeDark) selectedTheme.string = resources.getString(R.string.themeDark)
} }
"black" -> { "black" -> {
binding.switchBuffet.setTextColor(activity!!.resources.getColor(R.color.textPrimaryDark, activity!!.theme)) binding.switchBuffet.setTextColor(requireActivity().resources.getColor(R.color.textPrimaryDark, requireActivity().theme))
selectedTheme = DataTypes.Theme.Black selectedTheme = DataTypes.Theme.Black
selectedTheme.string = resources.getString(R.string.themeBlack) selectedTheme.string = resources.getString(R.string.themeBlack)
} }
@ -113,7 +115,7 @@ class SettingsFragment : Fragment() {
private fun initActions() { private fun initActions() {
binding.linLayoutUser.setOnClickListener { binding.linLayoutUser.setOnClickListener {
// open a new dialog // open a new dialog
LoginDialog(context!!) LoginDialog(requireContext())
.positiveButton { .positiveButton {
EncryptedPreferences.saveCredentials(email, password, context) EncryptedPreferences.saveCredentials(email, password, context)
} }
@ -129,13 +131,13 @@ class SettingsFragment : Fragment() {
} }
binding.linLayoutCourse.setOnClickListener { binding.linLayoutCourse.setOnClickListener {
CourseSelectionDialog(context!!).show { CourseSelectionDialog(requireContext()).show {
list = coursesList.map { it.courseName } list = coursesList.map { it.courseName }
listItems { listItems {
val loadingDialog = LoadingDialog(context) val loadingDialog = LoadingDialog(context)
loadingDialog.show() loadingDialog.show()
GlobalScope.launch(Dispatchers.Default) { lifecycleScope.launch(Dispatchers.Default) {
Preferences.saveCourse(context, coursesList[selectedIndex]) // save the course Preferences.saveCourse(context, coursesList[selectedIndex]) // save the course
// update current & next weeks timetable // update current & next weeks timetable
@ -164,7 +166,7 @@ class SettingsFragment : Fragment() {
} }
} }
MaterialDialog(context!!).show { MaterialDialog(requireContext()).show {
title(R.string.manage_lessons) title(R.string.manage_lessons)
positiveButton(R.string.delete) positiveButton(R.string.delete)
negativeButton(R.string.cancel) negativeButton(R.string.cancel)
@ -182,7 +184,7 @@ class SettingsFragment : Fragment() {
binding.linLayoutAbout.setOnClickListener { binding.linLayoutAbout.setOnClickListener {
// open a new info dialog // open a new info dialog
MaterialDialog(context!!) MaterialDialog(requireContext())
.title(R.string.about_dialog_heading) .title(R.string.about_dialog_heading)
.message(R.string.about_dialog_text) .message(R.string.about_dialog_text)
.show() .show()
@ -191,7 +193,7 @@ class SettingsFragment : Fragment() {
binding.linLayoutLicence.setOnClickListener { binding.linLayoutLicence.setOnClickListener {
// do the theme magic, as the lib's theme support is broken // do the theme magic, as the lib's theme support is broken
val outValue = TypedValue() val outValue = TypedValue()
context!!.theme.resolveAttribute(R.attr.themeName, outValue, true) requireContext().theme.resolveAttribute(R.attr.themeName, outValue, true)
val dialogCss = when (outValue.string) { val dialogCss = when (outValue.string) {
"light" -> R.string.license_dialog_style_light "light" -> R.string.license_dialog_style_light
@ -204,7 +206,7 @@ class SettingsFragment : Fragment() {
} }
// open a new license dialog // open a new license dialog
LicensesDialog.Builder(context!!) LicensesDialog.Builder(requireContext())
.setNotices(R.raw.notices) .setNotices(R.raw.notices)
.setTitle(R.string.licenses) .setTitle(R.string.licenses)
.setIncludeOwnLicense(true) .setIncludeOwnLicense(true)
@ -214,67 +216,67 @@ class SettingsFragment : Fragment() {
.show() .show()
} }
binding.linLayoutTheme.setOnClickListener { // binding.linLayoutTheme.setOnClickListener {
val themes = listOf( // val themes = listOf(
resources.getString(R.string.themeLight), // resources.getString(R.string.themeLight),
resources.getString(R.string.themeDark), // resources.getString(R.string.themeDark),
resources.getString(R.string.themeBlack) // resources.getString(R.string.themeBlack)
) // )
//
// MaterialDialog(requireContext()).show {
// title(R.string.theme)
// listItemsSingleChoice(items = themes, initialSelection = selectedTheme.ordinal) { _, index, _ ->
// Aesthetic.config {
// when (index) {
// 0 -> activityTheme(R.style.AppTheme_Light)
// 1 -> activityTheme(R.style.AppTheme_Dark)
// 2 -> activityTheme(R.style.AppTheme_Black)
// else -> activityTheme(R.style.AppTheme_Light)
// }
// apply()
// }
// }
// }
// }
MaterialDialog(context!!).show { // binding.linLayoutPrimaryColor.setOnClickListener {
title(R.string.theme) // // open a new color chooser dialog
listItemsSingleChoice(items = themes, initialSelection = selectedTheme.ordinal) { _, index, _ -> // MaterialDialog(requireContext())
Aesthetic.config { // .colorChooser(DataTypes().primaryColors, allowCustomArgb = true, initialSelection = Preferences.colorPrimary) { _, color ->
when (index) { // binding.viewPrimaryColor.setBackgroundColor(color)
0 -> activityTheme(R.style.AppTheme_Light) // Aesthetic.config {
1 -> activityTheme(R.style.AppTheme_Dark) // colorPrimary(color)
2 -> activityTheme(R.style.AppTheme_Black) // colorPrimaryDark(color)
else -> activityTheme(R.style.AppTheme_Light) // apply()
} // }
apply() // Preferences.saveColorPrimary(requireContext(), color)
} // }
} // .show {
} // title(R.string.primary_color)
} // positiveButton(R.string.select)
// getActionButton(WhichButton.POSITIVE).updateTextColor(Preferences.colorAccent)
// }
//
// }
binding.linLayoutPrimaryColor.setOnClickListener { // binding.linLayoutAccentColor.setOnClickListener {
// open a new color chooser dialog // // open a new color chooser dialog
MaterialDialog(context!!) // MaterialDialog(requireContext())
.colorChooser(DataTypes().primaryColors, allowCustomArgb = true, initialSelection = Preferences.colorPrimary) { _, color -> // .colorChooser(DataTypes().accentColors, allowCustomArgb = true, initialSelection = Preferences.colorAccent) { _, color ->
binding.viewPrimaryColor.setBackgroundColor(color) // binding.viewAccentColor.setBackgroundColor(color)
Aesthetic.config { // Aesthetic.config {
colorPrimary(color) // colorAccent(color)
colorPrimaryDark(color) // apply()
apply() // }
} //
Preferences.saveColorPrimary(context!!, color) // Preferences.saveColorAccent(requireContext(), color)
} // }
.show { // .show{
title(R.string.primary_color) // title(R.string.accent_color)
positiveButton(R.string.select) // positiveButton(R.string.select)
getActionButton(WhichButton.POSITIVE).updateTextColor(Preferences.colorAccent) // getActionButton(WhichButton.POSITIVE).updateTextColor(Preferences.colorAccent)
} // }
// }
}
binding.linLayoutAccentColor.setOnClickListener {
// open a new color chooser dialog
MaterialDialog(context!!)
.colorChooser(DataTypes().accentColors, allowCustomArgb = true, initialSelection = Preferences.colorAccent) { _, color ->
binding.viewAccentColor.setBackgroundColor(color)
Aesthetic.config {
colorAccent(color)
apply()
}
Preferences.saveColorAccent(context!!, color)
}
.show{
title(R.string.accent_color)
positiveButton(R.string.select)
getActionButton(WhichButton.POSITIVE).updateTextColor(Preferences.colorAccent)
}
}
binding.linLayoutGradesSync.setOnClickListener { binding.linLayoutGradesSync.setOnClickListener {
val items = resources.getStringArray(R.array.syncInterval).toList() val items = resources.getStringArray(R.array.syncInterval).toList()
@ -286,7 +288,7 @@ class SettingsFragment : Fragment() {
else -> 0 else -> 0
} }
MaterialDialog(context!!) MaterialDialog(requireContext())
.title(R.string.grades_sync) .title(R.string.grades_sync)
.listItemsSingleChoice(items = items, initialSelection = initial) { _, index, _ -> .listItemsSingleChoice(items = items, initialSelection = initial) { _, index, _ ->
val interval = when (index) { val interval = when (index) {
@ -297,8 +299,8 @@ class SettingsFragment : Fragment() {
else -> 0 else -> 0
} }
Preferences.saveGradesSync(context!!, interval) Preferences.saveGradesSync(requireContext(), interval)
GradesController.updateBackgroundSync(context!!) GradesController.updateBackgroundSync(requireContext())
binding.textGradesSyncDesc.text = if (Preferences.gradesSyncInterval == 0) { binding.textGradesSyncDesc.text = if (Preferences.gradesSyncInterval == 0) {
resources.getString(R.string.grades_sync_desc_never) resources.getString(R.string.grades_sync_desc_never)
@ -309,7 +311,7 @@ class SettingsFragment : Fragment() {
} }
binding.switchBuffet.setOnClickListener { binding.switchBuffet.setOnClickListener {
Preferences.saveShowBuffet(context!!, binding.switchBuffet.isChecked) Preferences.saveShowBuffet(requireContext(), binding.switchBuffet.isChecked)
} }
} }

View File

@ -27,6 +27,7 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.* import kotlinx.coroutines.*
import org.mosad.seil0.projectlaogai.R import org.mosad.seil0.projectlaogai.R
import org.mosad.seil0.projectlaogai.controller.cache.TimetableController import org.mosad.seil0.projectlaogai.controller.cache.TimetableController
@ -61,7 +62,7 @@ class TimetableFragment : Fragment() {
if (timetable.size > 1 && timetable[0].days.isNotEmpty() && timetable[1].days.isNotEmpty()) { if (timetable.size > 1 && timetable[0].days.isNotEmpty() && timetable[1].days.isNotEmpty()) {
initTimetable() initTimetable()
} else { } else {
val txtViewInfo = TextViewInfo(context!!).set { val txtViewInfo = TextViewInfo(requireContext()).set {
txt = resources.getString(R.string.timetable_generic_error) txt = resources.getString(R.string.timetable_generic_error)
}.showImage() }.showImage()
binding.linLayoutTimetable.addView(txtViewInfo) binding.linLayoutTimetable.addView(txtViewInfo)
@ -74,13 +75,13 @@ class TimetableFragment : Fragment() {
private fun initActions() { private fun initActions() {
binding.refreshLayoutTimetable.setOnRefreshListener { binding.refreshLayoutTimetable.setOnRefreshListener {
runBlocking { TimetableController.update(context!!).joinAll() } runBlocking { TimetableController.update(requireContext()).joinAll() }
reloadTimetableUI() reloadTimetableUI()
} }
// show the AddLessonDialog if the ftaBtn is clicked // show the AddLessonDialog if the ftaBtn is clicked
binding.faBtnAddSubject.setOnClickListener { binding.faBtnAddSubject.setOnClickListener {
AddSubjectDialog(context!!) AddSubjectDialog(requireContext())
.positiveButton { .positiveButton {
TimetableController.addSubject(selectedCourse, selectedSubject, context) TimetableController.addSubject(selectedCourse, selectedSubject, context)
runBlocking { reloadTimetableUI() } runBlocking { reloadTimetableUI() }
@ -101,16 +102,16 @@ class TimetableFragment : Fragment() {
/** /**
* add the current and next weeks lessons * add the current and next weeks lessons
*/ */
private fun initTimetable() = GlobalScope.launch(Dispatchers.Default) { private fun initTimetable() = lifecycleScope.launch(Dispatchers.Default) {
val currentDayIndex = NotRetardedCalendar.getDayOfWeekIndex() val currentDayIndex = NotRetardedCalendar.getDayOfWeekIndex()
addTimetableWeek(currentDayIndex, 5, 0).join() // add current week addTimetableWeek(currentDayIndex, 5, 0).join() // add current week
addTimetableWeek(0, currentDayIndex - 1, 1) // add next week addTimetableWeek(0, currentDayIndex - 1, 1) // add next week
} }
private fun addTimetableWeek(dayBegin: Int, dayEnd: Int, week: Int) = GlobalScope.launch(Dispatchers.Main) { private fun addTimetableWeek(dayBegin: Int, dayEnd: Int, week: Int) = lifecycleScope.launch(Dispatchers.Main) {
for (dayIndex in dayBegin..dayEnd) { for (dayIndex in dayBegin..dayEnd) {
val dayCardView = DayCardView(context!!) val dayCardView = DayCardView(requireContext())
// some wired calendar magic, calculate the correct date to be shown // some wired calendar magic, calculate the correct date to be shown
// ((timetable week - current week * 7) + (dayIndex - dayIndex of current week) // ((timetable week - current week * 7) + (dayIndex - dayIndex of current week)
@ -128,7 +129,7 @@ class TimetableFragment : Fragment() {
/** /**
* clear linLayout_Timetable, add the updated timetable * clear linLayout_Timetable, add the updated timetable
*/ */
private fun reloadTimetableUI() = GlobalScope.launch(Dispatchers.Default) { private fun reloadTimetableUI() = lifecycleScope.launch(Dispatchers.Default) {
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
// remove all lessons from the layout // remove all lessons from the layout
binding.linLayoutTimetable.removeAllViews() binding.linLayoutTimetable.removeAllViews()

View File

@ -41,7 +41,6 @@ class TextViewInfo(context: Context?): AppCompatTextView(context!!) {
init { init {
params.setMargins(0,200,0,0) params.setMargins(0,200,0,0)
} }
fun set(func: TextViewInfo.() -> Unit): TextViewInfo = apply { fun set(func: TextViewInfo.() -> Unit): TextViewInfo = apply {

View File

@ -1,13 +1,13 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules. // Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript { buildscript {
ext.kotlin_version = '1.4.20' ext.kotlin_version = '1.7.20'
repositories { repositories {
google() google()
jcenter() mavenCentral()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:4.1.1' classpath 'com.android.tools.build:gradle:7.3.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
@ -18,7 +18,7 @@ buildscript {
allprojects { allprojects {
repositories { repositories {
google() google()
jcenter() mavenCentral()
} }
} }