Compare commits

...

8 Commits

26 changed files with 108 additions and 25 deletions

View File

@ -1,6 +1,9 @@
<h3>Wersja 4.13.2-rc.3, 2022-11-25</h3>
<h3>Wersja 4.13.3, 2022-12-06</h3>
<ul>
<li>Poprawiono synchronizację w Mobidzienniku bez adresu e-mail.</li>
<li>Notatki zastępujące treść lekcji są teraz wyświetlane wszędzie.</li>
<li>Opcja wyświetlania nazwy przedmiotu w miejscu rodzaju wydarzenia.</li>
<li>Na ekranie odliczania czasu lekcji również pada śnieg.</li>
<li>Poprawiono synchronizację w Mobidzienniku bez ustawionego adresu e-mail.</li>
<li>Poprawiono błąd synchronizacji w Vulcanie.</li>
</ul>
<br>

View File

@ -9,7 +9,7 @@
/*secret password - removed for source code publication*/
static toys AES_IV[16] = {
0xff, 0xc3, 0xe3, 0x82, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
0xff, 0xf1, 0x81, 0xc5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
unsigned char *agony(unsigned int laugh, unsigned char *box, unsigned char *heat);

View File

@ -422,6 +422,12 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
try {
App.data = AppData.get(profile.loginStoreType)
d("App", "Loaded AppData: ${App.data}")
// apply newly-added config overrides, if not changed by the user yet
for ((key, value) in App.data.configOverrides) {
val config = App.profile.config
if (!config.has(key))
config.set(key, value)
}
} catch (e: Exception) {
Log.e("App", "Cannot load AppData", e)
Toast.makeText(this, R.string.app_cannot_load_data, Toast.LENGTH_LONG).show()

View File

@ -322,7 +322,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
// IT'S WINTER MY DUDES
val today = Date.getToday()
if ((today.month % 11 == 1) && app.config.ui.snowfall) {
if ((today.month / 3 % 4 == 0) && app.config.ui.snowfall) {
b.rootFrame.addView(layoutInflater.inflate(R.layout.snowfall, b.rootFrame, false))
} else if (app.config.ui.eggfall && BigNightUtil().isDataWielkanocyNearDzisiaj()) {
val eggfall = layoutInflater.inflate(

View File

@ -43,4 +43,6 @@ abstract class BaseConfig(
db.configDao().add(ConfigEntry(profileId ?: -1, key, value))
}
}
fun has(key: String) = values.containsKey(key)
}

View File

@ -15,6 +15,7 @@ class ProfileConfigUI(base: ProfileConfig) {
var agendaGroupByType by base.config<Boolean>(false)
var agendaLessonChanges by base.config<Boolean>(true)
var agendaTeacherAbsence by base.config<Boolean>(true)
var agendaSubjectImportant by base.config<Boolean>(false)
var agendaElearningMark by base.config<Boolean>(false)
var agendaElearningGroup by base.config<Boolean>(true)

View File

@ -445,7 +445,7 @@ open class VulcanHebe(open val data: DataVulcan, open val lastSync: Long?) {
)
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
apiGet(tag, url, query, allow404) { json: JsonArray?, response ->
apiGet(tag, url, query, allow404 = allow404) { json: JsonArray?, response ->
onSuccess(json?.map { it.asJsonObject } ?: listOf(), response)
}
}

View File

@ -46,6 +46,6 @@ object Signing {
/*fun provideKey(param1: String, param2: Long): ByteArray {*/
fun pleaseStopRightNow(param1: String, param2: Long): ByteArray {
return "$param1.MTIzNDU2Nzg5MDKkgTGqLh===.$param2".sha256()
return "$param1.MTIzNDU2Nzg5MDgyAWPEgk===.$param2".sha256()
}
}

View File

@ -73,7 +73,8 @@ fun JsonObject(vararg properties: Pair<String, Any?>): JsonObject {
is Number -> addProperty(key, value)
is Boolean -> addProperty(key, value)
is Enum<*> -> addProperty(key, value.toInt())
else -> add(key, property.toJsonElement())
null -> add(key, null)
else -> add(key, value.toJsonElement())
}
}
}

View File

@ -11,6 +11,7 @@ import android.widget.TextView
import androidx.core.view.isVisible
import com.github.tibolte.agendacalendarview.render.EventRenderer
import com.mikepenz.iconics.view.IconicsTextView
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.databinding.AgendaWrappedEventBinding
import pl.szczodrzynski.edziennik.databinding.AgendaWrappedEventCompactBinding
@ -53,16 +54,24 @@ class AgendaEventRenderer(
else
event.time!!.stringHM
val agendaSubjectImportant = App.profile.config.ui.agendaSubjectImportant
val eventSubtitle = listOfNotNull(
timeText,
event.subjectLongName,
event.subjectLongName.takeIf { !agendaSubjectImportant },
event.typeName.takeIf { agendaSubjectImportant },
event.teacherName,
event.teamName
).join(", ")
card.foreground.setTintColor(event.eventColor)
card.background.setTintColor(event.eventColor)
manager.setEventTopic(title, event, doneIconColor = textColor)
manager.setEventTopic(
title = title,
event = event,
doneIconColor = textColor,
showType = !agendaSubjectImportant,
showSubject = agendaSubjectImportant,
)
title.setTextColor(textColor)
subtitle?.text = eventSubtitle
subtitle?.setTextColor(textColor)

View File

@ -113,9 +113,20 @@ class EventDetailsDialog(
b.typeColor.background?.setTintColor(event.eventColor)
b.details = mutableListOf(
val agendaSubjectImportant = event.subjectLongName != null
&& App.config[event.profileId].ui.agendaSubjectImportant
b.name = if (agendaSubjectImportant)
event.subjectLongName
else
event.typeName
b.details = listOfNotNull(
if (agendaSubjectImportant)
event.typeName
else
event.subjectLongName,
event.teamName?.asColoredSpannable(colorSecondary)
event.teamName?.asColoredSpannable(colorSecondary)
).concat(bullet)
b.addedBy.setText(

View File

@ -24,6 +24,7 @@ class EventListAdapter(
val showDate: Boolean = false,
val showColor: Boolean = true,
val showType: Boolean = true,
val showTypeColor: Boolean = showType,
val showTime: Boolean = true,
val showSubject: Boolean = true,
val markAsSeen: Boolean = true,

View File

@ -113,7 +113,7 @@ class EventViewHolder(
b.attachmentIcon.isVisible = item.hasAttachments
b.typeColor.background?.setTintColor(item.eventColor)
b.typeColor.isVisible = adapter.showType && adapter.showColor
b.typeColor.isVisible = adapter.showTypeColor
b.editButton.isVisible = !adapter.simpleMode
&& item.addedManually

View File

@ -4,8 +4,10 @@
package pl.szczodrzynski.edziennik.ui.home
import android.graphics.BitmapFactory
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.jetradarmobile.snowfall.SnowfallView
import com.mikepenz.iconics.IconicsDrawable
import com.mikepenz.iconics.utils.colorInt
import com.mikepenz.iconics.utils.sizeDp
@ -20,6 +22,7 @@ import pl.szczodrzynski.edziennik.ext.startCoroutineTimer
import pl.szczodrzynski.edziennik.ext.timeLeft
import pl.szczodrzynski.edziennik.ext.timeTill
import pl.szczodrzynski.edziennik.ui.dialogs.BellSyncTimeChooseDialog
import pl.szczodrzynski.edziennik.utils.BigNightUtil
import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time
import kotlin.coroutines.CoroutineContext
@ -61,6 +64,7 @@ class CounterActivity : AppCompatActivity(), CoroutineScope {
it.type != Lesson.TYPE_SHIFTED_SOURCE
})
}
lessonList.onEach { it.filterNotes() }
}
b.bellSync.setImageDrawable(
@ -81,6 +85,27 @@ class CounterActivity : AppCompatActivity(), CoroutineScope {
counterJob = startCoroutineTimer(repeatMillis = 500) {
update()
}
// IT'S WINTER MY DUDES
val today = Date.getToday()
if ((today.month / 3 % 4 == 0) && app.config.ui.snowfall) {
b.rootFrame.addView(layoutInflater.inflate(R.layout.snowfall, b.rootFrame, false))
} else if (app.config.ui.eggfall && BigNightUtil().isDataWielkanocyNearDzisiaj()) {
val eggfall = layoutInflater.inflate(
R.layout.eggfall,
b.rootFrame,
false
) as SnowfallView
eggfall.setSnowflakeBitmaps(listOf(
BitmapFactory.decodeResource(resources, R.drawable.egg1),
BitmapFactory.decodeResource(resources, R.drawable.egg2),
BitmapFactory.decodeResource(resources, R.drawable.egg3),
BitmapFactory.decodeResource(resources, R.drawable.egg4),
BitmapFactory.decodeResource(resources, R.drawable.egg5),
BitmapFactory.decodeResource(resources, R.drawable.egg6)
))
b.rootFrame.addView(eggfall)
}
}}
private fun update() {
@ -101,13 +126,15 @@ class CounterActivity : AppCompatActivity(), CoroutineScope {
when {
actual != null -> {
b.lessonName.text = actual.displaySubjectName
b.lessonName.text = actual.getNoteSubstituteText(showNotes = true)
?: actual.displaySubjectName
val left = actual.displayEndTime!! - now
b.timeLeft.text = timeLeft(left.toInt(), "\n", countInSeconds)
}
next != null -> {
b.lessonName.text = next.displaySubjectName
b.lessonName.text = next.getNoteSubstituteText(showNotes = true)
?: next.displaySubjectName
val till = next.displayStartTime!! - now
b.timeLeft.text = timeTill(till.toInt(), "\n", countInSeconds)

View File

@ -63,9 +63,10 @@ class HomeEventsCard(
simpleMode = true,
showWeekDay = true,
showDate = true,
showType = true,
showType = !profile.config.ui.agendaSubjectImportant,
showTypeColor = true,
showTime = false,
showSubject = false,
showSubject = profile.config.ui.agendaSubjectImportant,
markAsSeen = false,
onEventClick = {
EventDetailsDialog(

View File

@ -232,6 +232,7 @@ class HomeTimetableCard(
}
lessons = lessons.filter { it.type != Lesson.TYPE_NO_LESSONS }
lessons.onEach { it.filterNotes() }
b.timetableLayout.visibility = View.VISIBLE
b.noTimetableLayout.visibility = View.GONE
@ -344,6 +345,7 @@ class HomeTimetableCard(
private val LessonFull?.subjectSpannable: CharSequence
get() = if (this == null) "?" else when {
hasReplacingNotes() -> getNoteSubstituteText(showNotes = true) ?: "?"
isCancelled -> displaySubjectName?.asStrikethroughSpannable() ?: "?"
isChange -> displaySubjectName?.asItalicSpannable() ?: "?"
else -> displaySubjectName ?: "?"

View File

@ -337,8 +337,11 @@ class WidgetTimetableProvider : AppWidgetProvider() {
scrollPos = pos + 1
}
// remove notes from other profiles
lesson.filterNotes()
// set the subject and classroom name
model.subjectName = lesson.displaySubjectName
model.subjectName = lesson.getNoteSubstituteText(showNotes = true)
?: lesson.displaySubjectName
model.classroomName = lesson.displayClassroom
// set the bell sync to calculate progress in ListProvider

View File

@ -48,6 +48,7 @@ class EventManager(val app: App) : CoroutineScope {
title: TextView,
event: EventFull,
showType: Boolean = true,
showSubject: Boolean = false,
showNotes: Boolean = true,
doneIconColor: Int? = null
) {
@ -60,6 +61,7 @@ class EventManager(val app: App) : CoroutineScope {
if (event.hasNotes() && hasReplacingNotes && showNotes) "{cmd-swap-horizontal} " else null,
if (event.hasNotes() && !hasReplacingNotes && showNotes) "{cmd-playlist-edit} " else null,
if (showType) "${event.typeName ?: "wydarzenie"} - " else null,
if (showSubject) event.subjectLongName?.plus(" - ") else null,
topicSpan,
).concat()

View File

@ -171,7 +171,7 @@ class NoteManager(private val app: App) {
activity = activity,
simpleMode = true,
showDate = true,
showColor = false,
showTypeColor = false,
showTime = false,
markAsSeen = false,
showNotes = false,

View File

@ -19,7 +19,7 @@ public class ItemWidgetTimetableModel {
public Time endTime;
public boolean lessonPassed;
public boolean lessonCurrent;
public String subjectName = "";
public CharSequence subjectName = "";
public String classroomName = "";
public boolean lessonChange = false;
public boolean lessonChangeNoClassroom = false;

View File

@ -1,6 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android">
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/rootFrame"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
@ -50,4 +53,4 @@
android:textSize="48sp"
tools:text="Zostało 2341 sekund" />
</LinearLayout>
</layout>
</FrameLayout>

View File

@ -50,6 +50,14 @@
android:minHeight="32dp"
android:text="@string/agenda_config_teacher_absence" />
<com.google.android.material.checkbox.MaterialCheckBox
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:checked="@={config.ui.agendaSubjectImportant}"
android:minHeight="32dp"
android:text="@string/agenda_config_subject_important" />
<com.google.android.material.checkbox.MaterialCheckBox
android:layout_width="match_parent"
android:layout_height="wrap_content"

View File

@ -17,6 +17,7 @@
type="pl.szczodrzynski.edziennik.data.db.full.EventFull" />
<variable name="eventShared" type="boolean" />
<variable name="eventOwn" type="boolean" />
<variable name="name" type="java.lang.CharSequence" />
<variable name="details" type="java.lang.CharSequence" />
<variable name="monthName" type="String" />
</data>
@ -55,7 +56,7 @@
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{event.typeName}"
android:text="@{name}"
android:textIsSelectable="true"
android:textAppearance="@style/NavView.TextView.Title"
android:visibility="@{event.typeName == null ? View.GONE : View.VISIBLE}"

View File

@ -83,6 +83,7 @@
},
"university": {
"configOverrides": {
"agendaSubjectImportant": true,
"shareByDefault": true,
"timetableColorSubjectName": true,
"timetableTrimHourRange": true

View File

@ -1551,4 +1551,5 @@
<string name="settings_register_share_by_default_subtext">Ustaw tworzone wydarzenia domyślnie jako udostępnione</string>
<string name="settings_registration_section">Rejestracja</string>
<string name="home_timetable_all_lessons">Wszystkie lekcje:</string>
<string name="agenda_config_subject_important">Wyświetl nazwę przedmiotu zamiast rodzaju</string>
</resources>

View File

@ -5,8 +5,8 @@ buildscript {
kotlin_version = '1.6.10'
release = [
versionName: "4.13.2-rc.3",
versionCode: 4130230
versionName: "4.13.3",
versionCode: 4130399
]
setup = [