Compare commits

...

2 Commits

9 changed files with 35 additions and 16 deletions

View File

@ -89,6 +89,7 @@ android {
buildFeatures { buildFeatures {
dataBinding = true dataBinding = true
viewBinding = true viewBinding = true
buildConfig true
} }
compileOptions { compileOptions {
coreLibraryDesugaringEnabled = true coreLibraryDesugaringEnabled = true
@ -192,14 +193,14 @@ dependencies {
implementation "eu.szkolny:material-about-library:1d5ebaf47c" implementation "eu.szkolny:material-about-library:1d5ebaf47c"
implementation "eu.szkolny:mhttp:af4b62e6e9" implementation "eu.szkolny:mhttp:af4b62e6e9"
implementation "eu.szkolny:nachos:0e5dfcaceb" implementation "eu.szkolny:nachos:0e5dfcaceb"
implementation "eu.szkolny.selective-dao:annotation:27f8f3f194" implementation "eu.szkolny.selective-dao:annotation:6a337f9"
officialImplementation "eu.szkolny:ssl-provider:1.0.0" officialImplementation "eu.szkolny:ssl-provider:1.0.0"
unofficialImplementation "eu.szkolny:ssl-provider:1.0.0" unofficialImplementation "eu.szkolny:ssl-provider:1.0.0"
implementation "pl.szczodrzynski:numberslidingpicker:2921225f76" implementation "pl.szczodrzynski:numberslidingpicker:2921225f76"
implementation "pl.szczodrzynski:recyclertablayout:700f980584" implementation "pl.szczodrzynski:recyclertablayout:700f980584"
implementation "pl.szczodrzynski:tachyon:551943a6b5" implementation "pl.szczodrzynski:tachyon:551943a6b5"
kapt "eu.szkolny.selective-dao:codegen:27f8f3f194" kapt "eu.szkolny.selective-dao:codegen:6a337f9"
// Iconics & related // Iconics & related
implementation "com.mikepenz:iconics-core:5.3.2" implementation "com.mikepenz:iconics-core:5.3.2"

View File

@ -124,7 +124,8 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
private val job = Job() private val job = Job()
override val coroutineContext: CoroutineContext override val coroutineContext: CoroutineContext
get() = job + Dispatchers.Main get() = job + Dispatchers.Main
override fun getWorkManagerConfiguration() = Configuration.Builder()
override val workManagerConfiguration: Configuration = Configuration.Builder()
.setMinimumLoggingLevel(Log.VERBOSE) .setMinimumLoggingLevel(Log.VERBOSE)
.build() .build()

View File

@ -144,7 +144,7 @@ class ConfigDelegate<T>(
java.lang.Float::class.java -> value.toFloatOrNull() java.lang.Float::class.java -> value.toFloatOrNull()
// enums, maps & collections // enums, maps & collections
else -> when { else -> when {
Enum::class.java.isAssignableFrom(type) -> value.toIntOrNull()?.toEnum(type) as Enum<*> Enum::class.java.isAssignableFrom(type) -> value.toIntOrNull()?.toEnum(type) as Enum
Collection::class.java.isAssignableFrom(type) -> { Collection::class.java.isAssignableFrom(type) -> {
val array = value.toJsonArray() val array = value.toJsonArray()
val genericType = getGenericType() val genericType = getGenericType()

View File

@ -391,7 +391,7 @@ open class VulcanHebe(open val data: DataVulcan, open val lastSync: Long?) {
fun apiGetList( fun apiGetList(
tag: String, tag: String,
endpoint: String, endpoint: String,
filterType: HebeFilterType? = null, filterType: HebeFilterType = HebeFilterType.BY_PUPIL,
dateFrom: Date? = null, dateFrom: Date? = null,
dateTo: Date? = null, dateTo: Date? = null,
lastSync: Long? = null, lastSync: Long? = null,
@ -424,8 +424,6 @@ open class VulcanHebe(open val data: DataVulcan, open val lastSync: Long?) {
HebeFilterType.BY_MESSAGEBOX -> { HebeFilterType.BY_MESSAGEBOX -> {
query["box"] = messageBox ?: data.messageBoxKey ?: "" query["box"] = messageBox ?: data.messageBoxKey ?: ""
} }
null -> TODO()
} }
if (dateFrom != null) if (dateFrom != null)

View File

@ -23,20 +23,24 @@ object WorkerUtils {
inline fun scheduleNext(app: App, rescheduleIfFailedFound: Boolean = true, crossinline onReschedule: () -> Unit) { inline fun scheduleNext(app: App, rescheduleIfFailedFound: Boolean = true, crossinline onReschedule: () -> Unit) {
AsyncTask.execute { AsyncTask.execute {
val workManager = WorkManager.getInstance(app) as WorkManagerImpl val workManager = WorkManager.getInstance(app) as WorkManagerImpl
val scheduledWork = workManager.workDatabase.workSpecDao().scheduledWork val scheduledWork = workManager.workDatabase.workSpecDao().getScheduledWork() as MutableList;
scheduledWork.forEach { scheduledWork.forEach {
Utils.d("WorkerUtils", "Work: ${it.id} at ${(it.periodStartTime + it.initialDelay).formatDate()}. State = ${it.state} (finished = ${it.state.isFinished})") Utils.d("WorkerUtils", "Work: ${it.id} at ${it.calculateNextRunTime().formatDate()}. State = ${it.state} (finished = ${it.state.isFinished})")
} }
// remove finished work and other than SyncWorker // remove finished work and other than SyncWorker
scheduledWork.removeAll { it.workerClassName != SyncWorker::class.java.canonicalName || it.isPeriodic || it.state.isFinished } scheduledWork.removeAll { it.workerClassName != SyncWorker::class.java.canonicalName || it.isPeriodic || it.state.isFinished }
Utils.d("WorkerUtils", "Found ${scheduledWork.size} unfinished work") Utils.d("WorkerUtils", "Found ${scheduledWork.size} unfinished work")
// remove all enqueued work that had to (but didn't) run at some point in the past (at least 1min ago) // remove all enqueued work that had to (but didn't) run at some point in the past (at least 1min ago)
val failedWork = scheduledWork.filter { it.state == WorkInfo.State.ENQUEUED && it.periodStartTime + it.initialDelay < System.currentTimeMillis() - 1 * MINUTE * 1000 } val failedWork = scheduledWork.filter { it.state == WorkInfo.State.ENQUEUED && it.calculateNextRunTime() < System.currentTimeMillis() - 1 * MINUTE * 1000 }
Utils.d("WorkerUtils", "${failedWork.size} work requests failed to start (out of ${scheduledWork.size} requests)") Utils.d("WorkerUtils", "${failedWork.size} work requests failed to start (out of ${scheduledWork.size} requests)")
if (rescheduleIfFailedFound) { if (rescheduleIfFailedFound) {
if (failedWork.isNotEmpty()) { if (failedWork.isNotEmpty()) {
Utils.d("WorkerUtils", "App Manager detected!") Utils.d("WorkerUtils", "App Manager detected!")
EventBus.getDefault().postSticky(AppManagerDetectedEvent(failedWork.map { it.periodStartTime + it.initialDelay })) EventBus.getDefault().postSticky(AppManagerDetectedEvent(failedWork.map { it.calculateNextRunTime() }))
} }
if (scheduledWork.size - failedWork.size < 1) { if (scheduledWork.size - failedWork.size < 1) {
Utils.d("WorkerUtils", "No pending work found, scheduling next:") Utils.d("WorkerUtils", "No pending work found, scheduling next:")

View File

@ -129,7 +129,7 @@ class LabProfileFragment : LazyFragment(), CoroutineScope {
is String -> input is String -> input
is Long -> input.toLong() is Long -> input.toLong()
is Double -> input.toDouble() is Double -> input.toDouble()
is Enum<*> -> input.toInt().toEnum(objVal::class.java) is Enum<*> -> input.toInt().toEnum(objVal::class.java) as Enum
else -> input else -> input
} }
field.set(parent, newVal) field.set(parent, newVal)

View File

@ -328,7 +328,7 @@ class HomeTimetableCard(
for (lesson in nextLessons) { for (lesson in nextLessons) {
text += listOf( text += listOf(
lesson.displayStartTime?.stringHM, adjustTimeWidth(lesson.displayStartTime?.stringHM),
lesson.subjectSpannable lesson.subjectSpannable
).concat(" ") ).concat(" ")
} }
@ -337,6 +337,12 @@ class HomeTimetableCard(
b.nextLessons.text = text.concat("\n") b.nextLessons.text = text.concat("\n")
}} }}
private fun adjustTimeWidth(time: String?) = when {
time == null -> ""
time.length == 4 -> " $time "
else -> "$time "
}
private val LessonFull?.subjectSpannable: CharSequence private val LessonFull?.subjectSpannable: CharSequence
get() = if (this == null) "?" else when { get() = if (this == null) "?" else when {
hasReplacingNotes() -> getNoteSubstituteText(showNotes = true) ?: "?" hasReplacingNotes() -> getNoteSubstituteText(showNotes = true) ?: "?"

View File

@ -4,11 +4,13 @@
package pl.szczodrzynski.edziennik.ui.timetable package pl.szczodrzynski.edziennik.ui.timetable
import android.annotation.SuppressLint
import android.content.BroadcastReceiver import android.content.BroadcastReceiver
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.IntentFilter import android.content.IntentFilter
import android.os.AsyncTask import android.os.AsyncTask
import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
@ -90,9 +92,17 @@ class TimetableFragment : Fragment(), CoroutineScope {
} }
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
activity.registerReceiver(broadcastReceiver, IntentFilter(ACTION_SCROLL_TO_DATE ),
Context.RECEIVER_NOT_EXPORTED)
activity.registerReceiver(broadcastReceiver, IntentFilter(ACTION_RELOAD_PAGES),
Context.RECEIVER_NOT_EXPORTED)
} else @Suppress("UnspecifiedRegisterReceiverFlag") {
activity.registerReceiver(broadcastReceiver, IntentFilter(ACTION_SCROLL_TO_DATE)) activity.registerReceiver(broadcastReceiver, IntentFilter(ACTION_SCROLL_TO_DATE))
activity.registerReceiver(broadcastReceiver, IntentFilter(ACTION_RELOAD_PAGES)) activity.registerReceiver(broadcastReceiver, IntentFilter(ACTION_RELOAD_PAGES))
} }
}
override fun onPause() { override fun onPause() {
super.onPause() super.onPause()
activity.unregisterReceiver(broadcastReceiver) activity.unregisterReceiver(broadcastReceiver)

View File

@ -11,7 +11,6 @@
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true # org.gradle.parallel=true
#Tue Aug 22 15:52:38 CEST 2023 #Tue Aug 22 15:52:38 CEST 2023
android.defaults.buildfeatures.buildconfig=true
android.enableJetifier=true android.enableJetifier=true
android.nonFinalResIds=false android.nonFinalResIds=false
android.nonTransitiveRClass=false android.nonTransitiveRClass=false