Compare commits

..

7 Commits

15 changed files with 82 additions and 48 deletions

View File

@ -1,4 +1,4 @@
<h3>Wersja 4.0-beta.6, 2020-01-28</h3>
<h3>Wersja 4.0-beta.7, 2020-02-08</h3>
<ul>
<li><b>Przebudowaliśmy cały moduł synchronizacji</b>, co oznacza większą stabilność aplikacji, szybkosć oraz poprawność pobieranych danych.</li>
<li><b><u>Wysyłanie wiadomości</u></b> - funkcja, na którą czekał każdy. Od teraz w Szkolnym można wysyłać oraz odpowiadać na wiadomości do nauczycieli &#x1F44F;</li>
@ -32,10 +32,5 @@ Staramy się usuwać takie przypadki, jednak na chwilę obecną mogą występowa
<br>
<br>
<br>
<br>
<i>Okazja ograniczona czasowo:</i> Poczuj prawdziwą zimę, włączając w Ustawieniach widok padającego śniegu!
<br>
<br>
<br>
Dzięki za korzystanie ze Szkolnego!<br>
<i>&copy; Kuba Szczodrzyński, Kacper Ziubryniewicz 2020</i>

View File

@ -9,7 +9,7 @@
/*secret password - removed for source code publication*/
static toys AES_IV[16] = {
0x4a, 0x83, 0xba, 0x71, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
0x21, 0xd7, 0x64, 0x86, 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

@ -7,7 +7,7 @@ package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan
import pl.szczodrzynski.edziennik.data.api.*
import pl.szczodrzynski.edziennik.data.api.models.Feature
const val ENDPOINT_VULCAN_API_STUDENT_LIST = 1000
const val ENDPOINT_VULCAN_API_UPDATE_SEMESTER = 1000
const val ENDPOINT_VULCAN_API_DICTIONARIES = 1010
const val ENDPOINT_VULCAN_API_TIMETABLE = 1020
const val ENDPOINT_VULCAN_API_EVENTS = 1030
@ -54,7 +54,7 @@ val VulcanFeatures = listOf(
), listOf(LOGIN_METHOD_VULCAN_API)),
Feature(LOGIN_TYPE_VULCAN, FEATURE_ALWAYS_NEEDED, listOf(
ENDPOINT_VULCAN_API_STUDENT_LIST to LOGIN_METHOD_VULCAN_API,
ENDPOINT_VULCAN_API_UPDATE_SEMESTER to LOGIN_METHOD_VULCAN_API,
ENDPOINT_VULCAN_API_DICTIONARIES to LOGIN_METHOD_VULCAN_API
), listOf(LOGIN_METHOD_VULCAN_API))
/*Feature(LOGIN_TYPE_VULCAN, FEATURE_STUDENT_INFO, listOf(

View File

@ -36,6 +36,10 @@ class VulcanData(val data: DataVulcan, val onSuccess: () -> Unit) {
private fun useEndpoint(endpointId: Int, onSuccess: () -> Unit) {
Utils.d(TAG, "Using endpoint $endpointId")
when (endpointId) {
ENDPOINT_VULCAN_API_UPDATE_SEMESTER -> {
data.startProgress(R.string.edziennik_progress_endpoint_student_info)
VulcanApiUpdateSemester(data, onSuccess)
}
ENDPOINT_VULCAN_API_DICTIONARIES -> {
data.startProgress(R.string.edziennik_progress_endpoint_dictionaries)
VulcanApiDictionaries(data, onSuccess)

View File

@ -1,13 +1,14 @@
/*
* Copyright (c) Kuba Szczodrzyński 2020-1-3.
* Copyright (c) Kuba Szczodrzyński 2020-2-1.
*/
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.login
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.api
import pl.szczodrzynski.edziennik.*
import pl.szczodrzynski.edziennik.data.api.ERROR_NO_STUDENTS_IN_ACCOUNT
import pl.szczodrzynski.edziennik.data.api.VULCAN_API_ENDPOINT_STUDENT_LIST
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_API_UPDATE_SEMESTER
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanApi
import pl.szczodrzynski.edziennik.data.api.models.ApiError
import pl.szczodrzynski.edziennik.utils.models.Date
@ -66,6 +67,7 @@ class VulcanApiUpdateSemester(override val data: DataVulcan, val onSuccess: () -
dateYearEnd?.let { profile.dateYearEnd = it }
}
data.setSyncNext(ENDPOINT_VULCAN_API_UPDATE_SEMESTER, if (data.studentSemesterNumber == 2) 7*DAY else 2*DAY)
onSuccess()
}
} ?: onSuccess()}

View File

@ -13,6 +13,7 @@ import io.github.wulkanowy.signer.android.getPrivateKeyFromCert
import pl.szczodrzynski.edziennik.currentTimeUnix
import pl.szczodrzynski.edziennik.data.api.*
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.api.VulcanApiUpdateSemester
import pl.szczodrzynski.edziennik.data.api.models.ApiError
import pl.szczodrzynski.edziennik.getJsonObject
import pl.szczodrzynski.edziennik.getString

View File

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

View File

@ -120,11 +120,15 @@ interface TimetableDao {
@Query("""
SELECT
timetable.*,
subjects.subjectLongName AS subjectName,
teachers.teacherName ||" "|| teachers.teacherSurname AS teacherName,
oldS.subjectLongName AS oldSubjectName,
oldT.teacherName ||" "|| oldT.teacherSurname AS oldTeacherName,
metadata.seen, metadata.notified, metadata.addedDate
FROM timetable
LEFT JOIN subjects USING(profileId, subjectId)
LEFT JOIN teachers USING(profileId, teacherId)
LEFT JOIN subjects AS oldS ON timetable.profileId = oldS.profileId AND timetable.oldSubjectId = oldS.subjectId
LEFT JOIN teachers AS oldT ON timetable.profileId = oldT.profileId AND timetable.oldTeacherId = oldT.teacherId
LEFT JOIN metadata ON id = thingId AND thingType = ${Metadata.TYPE_LESSON_CHANGE} AND metadata.profileId = timetable.profileId
WHERE timetable.type NOT IN (${Lesson.TYPE_NORMAL}, ${Lesson.TYPE_NO_LESSONS}, ${Lesson.TYPE_SHIFTED_SOURCE}) AND metadata.notified = 0

View File

@ -21,7 +21,7 @@ class Migration56 : Migration(55, 56) {
profileId INTEGER NOT NULL,
lessonRangeNumber INTEGER NOT NULL,
lessonRangeStart TEXT NOT NULL,
LessonRangeEnd TEXT NOT NULL,
lessonRangeEnd TEXT NOT NULL,
PRIMARY KEY(profileId, lessonRangeNumber))""")
}
}

View File

@ -10,26 +10,25 @@ import androidx.sqlite.db.SupportSQLiteDatabase
class Migration76 : Migration(75, 76) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE feedbackMessages RENAME TO _feedbackMessages;")
database.execSQL("CREATE TABLE feedbackMessages (\n" +
"\tmessageId INTEGER NOT NULL PRIMARY KEY,\n" +
"\treceived INTEGER NOT NULL,\n" +
"\ttext TEXT NOT NULL,\n" +
"\tsenderName TEXT NOT NULL,\n" +
"\tdeviceId TEXT DEFAULT NULL,\n" +
"\tdeviceName TEXT DEFAULT NULL,\n" +
"\tdevId INTEGER DEFAULT NULL,\n" +
"\tdevImage TEXT DEFAULT NULL,\n" +
"\tsentTime INTEGER NOT NULL\n" +
");")
database.execSQL("INSERT INTO feedbackMessages (messageId, received, text, senderName, deviceId, deviceName, devId, devImage, sentTime)\n" +
"SELECT messageId, received, text,\n" +
"CASE fromUser IS NOT NULL WHEN 1 THEN CASE fromUserName IS NULL WHEN 1 THEN \"\" ELSE fromUserName END ELSE \"\" END AS senderName,\n" +
"fromUser AS deviceId,\n" +
"NULL AS deviceName,\n" +
"CASE received AND fromUser IS NULL WHEN 1 THEN 100 ELSE NULL END AS devId,\n" +
"NULL AS devImage,\n" +
"sentTime\n" +
"FROM _feedbackMessages;")
database.execSQL("""CREATE TABLE feedbackMessages (
messageId INTEGER NOT NULL PRIMARY KEY,
received INTEGER NOT NULL,
text TEXT NOT NULL,
senderName TEXT NOT NULL,
deviceId TEXT DEFAULT NULL,
deviceName TEXT DEFAULT NULL,
devId INTEGER DEFAULT NULL,
devImage TEXT DEFAULT NULL,
sentTime INTEGER NOT NULL);""")
database.execSQL("""INSERT INTO feedbackMessages (messageId, received, text, senderName, deviceId, deviceName, devId, devImage, sentTime)
SELECT messageId, received, text,
CASE fromUser IS NOT NULL WHEN 1 THEN CASE fromUserName IS NULL WHEN 1 THEN "" ELSE fromUserName END ELSE "" END AS senderName,
fromUser AS deviceId,
NULL AS deviceName,
CASE received AND fromUser IS NULL WHEN 1 THEN 100 ELSE NULL END AS devId,
NULL AS devImage,
sentTime
FROM _feedbackMessages;""")
database.execSQL("DROP TABLE _feedbackMessages;")
}
}

View File

@ -10,6 +10,7 @@ import android.net.Uri
import android.os.Build
import android.os.Environment
import android.util.Log
import android.view.View
import android.view.View.MeasureSpec
import android.widget.LinearLayout
import android.widget.TextView
@ -60,6 +61,7 @@ class GenerateBlockTimetableDialog(
private lateinit var b: DialogGenerateBlockTimetableBinding
private var showProfileName: Boolean = false
private var showTeachersNames: Boolean = true
private var noColors: Boolean = false
init { run {
@ -78,6 +80,9 @@ class GenerateBlockTimetableDialog(
b.showProfileNameItem.onClick { b.showProfileNameCheckbox.trigger() }
b.showProfileNameCheckbox.setOnCheckedChangeListener { _, isChecked -> showProfileName = isChecked }
b.showTeachersNamesItem.onClick { b.showTeachersNamesCheckbox.trigger() }
b.showTeachersNamesCheckbox.setOnCheckedChangeListener { _, isChecked -> showTeachersNames = isChecked }
b.noColorsItem.onClick { b.noColorsCheckbox.trigger() }
b.noColorsCheckbox.setOnCheckedChangeListener { _, isChecked -> noColors = isChecked }
@ -221,6 +226,8 @@ class GenerateBlockTimetableDialog(
teacherName.text = lesson.displayTeacherName ?: ""
teamName.text = lesson.displayTeamName ?: ""
if (!showTeachersNames) teacherName.visibility = View.GONE
when (lesson.type) {
Lesson.TYPE_NORMAL -> {}
Lesson.TYPE_CANCELLED, Lesson.TYPE_SHIFTED_SOURCE -> {

View File

@ -22,14 +22,11 @@ import kotlinx.coroutines.*
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.MainActivity
import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.*
import pl.szczodrzynski.edziennik.data.api.events.FeedbackMessageEvent
import pl.szczodrzynski.edziennik.data.api.szkolny.SzkolnyApi
import pl.szczodrzynski.edziennik.data.db.entity.FeedbackMessage
import pl.szczodrzynski.edziennik.databinding.FragmentFeedbackBinding
import pl.szczodrzynski.edziennik.onClick
import pl.szczodrzynski.edziennik.utils.Themes
import pl.szczodrzynski.edziennik.utils.Utils
import pl.szczodrzynski.edziennik.utils.Utils.openUrl
@ -82,7 +79,7 @@ class FeedbackFragment : Fragment(), CoroutineScope {
0 to User(0, "Ja", null)
)
private fun getUser(message: FeedbackMessage): User {
val userId = message.devId ?: if (message.received) 1 else 0
val userId = message.devId ?: if (message.received) -message.senderName.crc16() else 0
return users[userId] ?: run {
User(userId, message.senderName, message.devImage).also { users[userId] = it }
}
@ -118,13 +115,11 @@ class FeedbackFragment : Fragment(), CoroutineScope {
}
private suspend fun loadMessages(messageList: List<FeedbackMessage>? = null) {
/*if (messageList != null && messageList.isNotEmpty())
return*/
val messages = messageList ?: withContext(Dispatchers.Default) {
val messages = withContext(Dispatchers.Default) {
if (currentDeviceId == null)
app.db.feedbackMessageDao().allNow
messageList ?: app.db.feedbackMessageDao().allNow
else
app.db.feedbackMessageDao().getByDeviceIdNow(currentDeviceId!!)
messageList?.filter { it.deviceId == currentDeviceId } ?: app.db.feedbackMessageDao().getByDeviceIdNow(currentDeviceId!!)
}
if (messages.isNotEmpty()) {
@ -172,14 +167,14 @@ class FeedbackFragment : Fragment(), CoroutineScope {
}
if (isDev) {
messages.firstOrNull { it.received }?.let {
messages.firstOrNull { it.received && it.devId == null }?.let {
currentDeviceId = it.deviceId
b.targetDeviceDropDown.setText("${it.senderName} (${it.deviceId}) - ${it.deviceName}")
}
// handle notification intent
arguments?.getString("feedbackMessageDeviceId")?.let { deviceId ->
currentDeviceId = deviceId
messages.firstOrNull { it.received && it.deviceId == deviceId }?.let {
messages.firstOrNull { it.received && it.deviceId == deviceId && it.devId == null }?.let {
currentDeviceId = deviceId
b.targetDeviceDropDown.setText("${it.senderName} (${it.deviceId}) - ${it.deviceName}")
}
}

View File

@ -34,6 +34,32 @@
android:text="@string/timetable_generate_show_profile_name" />
</LinearLayout>
<LinearLayout
android:id="@+id/showTeachersNamesItem"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:orientation="horizontal">
<CheckBox
android:id="@+id/showTeachersNamesCheckbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="4dp"
android:layout_marginBottom="4dp"
android:checked="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/timetable_generate_show_teachers_names" />
</LinearLayout>
<LinearLayout
android:id="@+id/noColorsItem"
android:layout_width="match_parent"

View File

@ -1173,4 +1173,5 @@
<string name="dialog_grades_config_color_by_value">Wg wartości oceny</string>
<string name="other">Inne</string>
<string name="menu_grades_config">Ustawienia ocen</string>
<string name="timetable_generate_show_teachers_names">Pokaż imiona i nazwiska nauczycieli</string>
</resources>

View File

@ -5,8 +5,8 @@ buildscript {
kotlin_version = '1.3.61'
release = [
versionName: "4.0-beta.6",
versionCode: 4000006
versionName: "4.0-beta.7",
versionCode: 4000007
]
setup = [