mirror of
https://github.com/wulkanowy/wulkanowy.git
synced 2025-01-31 18:52:45 +01:00
Merge branch 'bugfix/2.5.2'
This commit is contained in:
commit
e17129efea
4
.gitignore
vendored
4
.gitignore
vendored
@ -67,6 +67,10 @@ captures/
|
|||||||
.idea/discord.xml
|
.idea/discord.xml
|
||||||
.idea/migrations.xml
|
.idea/migrations.xml
|
||||||
.idea/androidTestResultsUserPreferences.xml
|
.idea/androidTestResultsUserPreferences.xml
|
||||||
|
.idea/copilot
|
||||||
|
.idea/deploymentTargetDropDown.xml
|
||||||
|
.idea/deploymentTargetSelector.xml
|
||||||
|
.idea/kotlinc.xml
|
||||||
|
|
||||||
# Keystore files
|
# Keystore files
|
||||||
*.jks
|
*.jks
|
||||||
|
@ -27,8 +27,8 @@ android {
|
|||||||
testApplicationId "io.github.tests.wulkanowy"
|
testApplicationId "io.github.tests.wulkanowy"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 34
|
targetSdkVersion 34
|
||||||
versionCode 150
|
versionCode 151
|
||||||
versionName "2.5.1"
|
versionName "2.5.2"
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
|
||||||
resValue "string", "app_name", "Wulkanowy"
|
resValue "string", "app_name", "Wulkanowy"
|
||||||
@ -165,7 +165,7 @@ play {
|
|||||||
track = 'production'
|
track = 'production'
|
||||||
releaseStatus = ReleaseStatus.IN_PROGRESS
|
releaseStatus = ReleaseStatus.IN_PROGRESS
|
||||||
userFraction = 0.50d
|
userFraction = 0.50d
|
||||||
updatePriority = 1
|
updatePriority = 3
|
||||||
enabled.set(false)
|
enabled.set(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,7 +195,7 @@ ext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'io.github.wulkanowy:sdk:2.5.1'
|
implementation 'io.github.wulkanowy:sdk:2.5.2'
|
||||||
|
|
||||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4'
|
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4'
|
||||||
|
|
||||||
|
2547
app/schemas/io.github.wulkanowy.data.db.AppDatabase/62.json
Normal file
2547
app/schemas/io.github.wulkanowy.data.db.AppDatabase/62.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -174,6 +174,7 @@ import javax.inject.Singleton
|
|||||||
AutoMigration(from = 58, to = 59),
|
AutoMigration(from = 58, to = 59),
|
||||||
AutoMigration(from = 59, to = 60),
|
AutoMigration(from = 59, to = 60),
|
||||||
AutoMigration(from = 60, to = 61),
|
AutoMigration(from = 60, to = 61),
|
||||||
|
AutoMigration(from = 61, to = 62),
|
||||||
],
|
],
|
||||||
version = AppDatabase.VERSION_SCHEMA,
|
version = AppDatabase.VERSION_SCHEMA,
|
||||||
exportSchema = true
|
exportSchema = true
|
||||||
@ -182,7 +183,7 @@ import javax.inject.Singleton
|
|||||||
abstract class AppDatabase : RoomDatabase() {
|
abstract class AppDatabase : RoomDatabase() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val VERSION_SCHEMA = 61
|
const val VERSION_SCHEMA = 62
|
||||||
|
|
||||||
fun getMigrations(sharedPrefProvider: SharedPrefProvider, appInfo: AppInfo) = arrayOf(
|
fun getMigrations(sharedPrefProvider: SharedPrefProvider, appInfo: AppInfo) = arrayOf(
|
||||||
Migration2(),
|
Migration2(),
|
||||||
|
@ -9,6 +9,7 @@ import androidx.room.Transaction
|
|||||||
import androidx.room.Update
|
import androidx.room.Update
|
||||||
import io.github.wulkanowy.data.db.entities.Semester
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
|
import io.github.wulkanowy.data.db.entities.StudentIsAuthorized
|
||||||
import io.github.wulkanowy.data.db.entities.StudentName
|
import io.github.wulkanowy.data.db.entities.StudentName
|
||||||
import io.github.wulkanowy.data.db.entities.StudentNickAndAvatar
|
import io.github.wulkanowy.data.db.entities.StudentNickAndAvatar
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
@ -23,6 +24,9 @@ abstract class StudentDao {
|
|||||||
@Delete
|
@Delete
|
||||||
abstract suspend fun delete(student: Student)
|
abstract suspend fun delete(student: Student)
|
||||||
|
|
||||||
|
@Update(entity = Student::class)
|
||||||
|
abstract suspend fun update(studentIsAuthorized: StudentIsAuthorized)
|
||||||
|
|
||||||
@Update(entity = Student::class)
|
@Update(entity = Student::class)
|
||||||
abstract suspend fun update(studentNickAndAvatar: StudentNickAndAvatar)
|
abstract suspend fun update(studentNickAndAvatar: StudentNickAndAvatar)
|
||||||
|
|
||||||
|
@ -78,6 +78,13 @@ data class Student(
|
|||||||
|
|
||||||
@ColumnInfo(name = "registration_date")
|
@ColumnInfo(name = "registration_date")
|
||||||
val registrationDate: Instant,
|
val registrationDate: Instant,
|
||||||
|
|
||||||
|
@ColumnInfo(name = "is_authorized", defaultValue = "0")
|
||||||
|
val isAuthorized: Boolean,
|
||||||
|
|
||||||
|
@ColumnInfo(name = "is_edu_one", defaultValue = "0")
|
||||||
|
val isEduOne: Boolean,
|
||||||
|
|
||||||
) : Serializable {
|
) : Serializable {
|
||||||
|
|
||||||
@PrimaryKey(autoGenerate = true)
|
@PrimaryKey(autoGenerate = true)
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
package io.github.wulkanowy.data.db.entities
|
||||||
|
|
||||||
|
import androidx.room.ColumnInfo
|
||||||
|
import androidx.room.Entity
|
||||||
|
import androidx.room.PrimaryKey
|
||||||
|
import java.io.Serializable
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
data class StudentIsAuthorized(
|
||||||
|
@ColumnInfo(name = "is_authorized", defaultValue = "0")
|
||||||
|
val isAuthorized: Boolean,
|
||||||
|
) : Serializable {
|
||||||
|
|
||||||
|
@PrimaryKey
|
||||||
|
var id: Long = 0
|
||||||
|
}
|
@ -34,17 +34,19 @@ fun SdkRegisterUser.mapToPojo(password: String?) = RegisterUser(
|
|||||||
error = it.error,
|
error = it.error,
|
||||||
students = it.subjects
|
students = it.subjects
|
||||||
.filterIsInstance<SdkRegisterStudent>()
|
.filterIsInstance<SdkRegisterStudent>()
|
||||||
.map { registerSubject ->
|
.map { registerStudent ->
|
||||||
RegisterStudent(
|
RegisterStudent(
|
||||||
studentId = registerSubject.studentId,
|
studentId = registerStudent.studentId,
|
||||||
studentName = registerSubject.studentName,
|
studentName = registerStudent.studentName,
|
||||||
studentSecondName = registerSubject.studentSecondName,
|
studentSecondName = registerStudent.studentSecondName,
|
||||||
studentSurname = registerSubject.studentSurname,
|
studentSurname = registerStudent.studentSurname,
|
||||||
className = registerSubject.className,
|
className = registerStudent.className,
|
||||||
classId = registerSubject.classId,
|
classId = registerStudent.classId,
|
||||||
isParent = registerSubject.isParent,
|
isParent = registerStudent.isParent,
|
||||||
semesters = registerSubject.semesters
|
isAuthorized = registerStudent.isAuthorized,
|
||||||
.mapToEntities(registerSubject.studentId),
|
isEduOne = registerStudent.isEduOne,
|
||||||
|
semesters = registerStudent.semesters
|
||||||
|
.mapToEntities(registerStudent.studentId),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -84,6 +86,8 @@ fun RegisterStudent.mapToStudentWithSemesters(
|
|||||||
password = user.password.orEmpty(),
|
password = user.password.orEmpty(),
|
||||||
isCurrent = false,
|
isCurrent = false,
|
||||||
registrationDate = Instant.now(),
|
registrationDate = Instant.now(),
|
||||||
|
isAuthorized = this.isAuthorized,
|
||||||
|
isEduOne = this.isEduOne,
|
||||||
).apply {
|
).apply {
|
||||||
avatarColor = colors.random()
|
avatarColor = colors.random()
|
||||||
},
|
},
|
||||||
|
@ -45,4 +45,6 @@ data class RegisterStudent(
|
|||||||
val classId: Int,
|
val classId: Int,
|
||||||
val isParent: Boolean,
|
val isParent: Boolean,
|
||||||
val semesters: List<Semester>,
|
val semesters: List<Semester>,
|
||||||
|
val isAuthorized: Boolean,
|
||||||
|
val isEduOne: Boolean
|
||||||
) : java.io.Serializable
|
) : java.io.Serializable
|
||||||
|
@ -6,6 +6,7 @@ import io.github.wulkanowy.data.db.dao.SemesterDao
|
|||||||
import io.github.wulkanowy.data.db.dao.StudentDao
|
import io.github.wulkanowy.data.db.dao.StudentDao
|
||||||
import io.github.wulkanowy.data.db.entities.Semester
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
|
import io.github.wulkanowy.data.db.entities.StudentIsAuthorized
|
||||||
import io.github.wulkanowy.data.db.entities.StudentName
|
import io.github.wulkanowy.data.db.entities.StudentName
|
||||||
import io.github.wulkanowy.data.db.entities.StudentNickAndAvatar
|
import io.github.wulkanowy.data.db.entities.StudentNickAndAvatar
|
||||||
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
||||||
@ -14,6 +15,7 @@ import io.github.wulkanowy.data.mappers.mapToPojo
|
|||||||
import io.github.wulkanowy.data.pojos.RegisterUser
|
import io.github.wulkanowy.data.pojos.RegisterUser
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
import io.github.wulkanowy.utils.DispatchersProvider
|
import io.github.wulkanowy.utils.DispatchersProvider
|
||||||
|
import io.github.wulkanowy.utils.getCurrentOrLast
|
||||||
import io.github.wulkanowy.utils.init
|
import io.github.wulkanowy.utils.init
|
||||||
import io.github.wulkanowy.utils.security.Scrambler
|
import io.github.wulkanowy.utils.security.Scrambler
|
||||||
import io.github.wulkanowy.utils.switchSemester
|
import io.github.wulkanowy.utils.switchSemester
|
||||||
@ -100,6 +102,25 @@ class StudentRepository @Inject constructor(
|
|||||||
return student
|
return student
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun checkCurrentStudentAuthorizationStatus() {
|
||||||
|
val student = getCurrentStudent()
|
||||||
|
|
||||||
|
if (!student.isAuthorized) {
|
||||||
|
val currentSemester = semesterDb.loadAll(
|
||||||
|
studentId = student.studentId,
|
||||||
|
classId = student.classId,
|
||||||
|
).getCurrentOrLast()
|
||||||
|
val initializedSdk = sdk.init(student).switchSemester(currentSemester)
|
||||||
|
val isAuthorized = initializedSdk.getCurrentStudent()?.isAuthorized ?: false
|
||||||
|
|
||||||
|
if (isAuthorized) {
|
||||||
|
studentDb.update(StudentIsAuthorized(isAuthorized = true).apply {
|
||||||
|
id = student.id
|
||||||
|
})
|
||||||
|
} else throw NoAuthorizationException()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun getCurrentStudent(decryptPass: Boolean = true): Student {
|
suspend fun getCurrentStudent(decryptPass: Boolean = true): Student {
|
||||||
val student = studentDb.loadCurrent() ?: throw NoCurrentStudentException()
|
val student = studentDb.loadCurrent() ?: throw NoCurrentStudentException()
|
||||||
|
|
||||||
@ -176,3 +197,6 @@ class StudentRepository @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class NoAuthorizationException : Exception()
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package io.github.wulkanowy.ui.base
|
package io.github.wulkanowy.ui.base
|
||||||
|
|
||||||
import android.app.ActivityManager
|
import android.app.ActivityManager
|
||||||
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
@ -45,11 +46,19 @@ abstract class BaseActivity<T : BasePresenter<out BaseView>, VB : ViewBinding> :
|
|||||||
themeManager.applyActivityTheme(this)
|
themeManager.applyActivityTheme(this)
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
supportFragmentManager.registerFragmentLifecycleCallbacks(fragmentLifecycleLogger, true)
|
supportFragmentManager.registerFragmentLifecycleCallbacks(fragmentLifecycleLogger, true)
|
||||||
|
applyCustomTaskDescription()
|
||||||
|
}
|
||||||
|
|
||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
setTaskDescription(
|
private fun applyCustomTaskDescription() {
|
||||||
ActivityManager.TaskDescription(null, null, getThemeAttrColor(R.attr.colorSurface))
|
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R) return
|
||||||
)
|
try {
|
||||||
|
val newColor = getThemeAttrColor(R.attr.colorSurface)
|
||||||
|
val taskDescription = ActivityManager.TaskDescription(null, null, newColor)
|
||||||
|
setTaskDescription(taskDescription)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Timber.e(e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun showError(text: String, error: Throwable) {
|
override fun showError(text: String, error: Throwable) {
|
||||||
|
@ -3,7 +3,7 @@ package io.github.wulkanowy.ui.base
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import io.github.wulkanowy.data.exceptions.NoCurrentStudentException
|
import io.github.wulkanowy.data.exceptions.NoCurrentStudentException
|
||||||
import io.github.wulkanowy.sdk.scrapper.exception.AuthorizationRequiredException
|
import io.github.wulkanowy.data.repositories.NoAuthorizationException
|
||||||
import io.github.wulkanowy.sdk.scrapper.exception.CloudflareVerificationException
|
import io.github.wulkanowy.sdk.scrapper.exception.CloudflareVerificationException
|
||||||
import io.github.wulkanowy.sdk.scrapper.login.BadCredentialsException
|
import io.github.wulkanowy.sdk.scrapper.login.BadCredentialsException
|
||||||
import io.github.wulkanowy.sdk.scrapper.login.PasswordChangeRequiredException
|
import io.github.wulkanowy.sdk.scrapper.login.PasswordChangeRequiredException
|
||||||
@ -40,7 +40,7 @@ open class ErrorHandler @Inject constructor(@ApplicationContext protected val co
|
|||||||
is ScramblerException -> onDecryptionFailed()
|
is ScramblerException -> onDecryptionFailed()
|
||||||
is BadCredentialsException -> onExpiredCredentials()
|
is BadCredentialsException -> onExpiredCredentials()
|
||||||
is NoCurrentStudentException -> onNoCurrentStudent()
|
is NoCurrentStudentException -> onNoCurrentStudent()
|
||||||
is AuthorizationRequiredException -> onAuthorizationRequired()
|
is NoAuthorizationException -> onAuthorizationRequired()
|
||||||
is CloudflareVerificationException -> onCaptchaVerificationRequired(error.originalUrl)
|
is CloudflareVerificationException -> onCaptchaVerificationRequired(error.originalUrl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package io.github.wulkanowy.ui.modules.attendance
|
package io.github.wulkanowy.ui.modules.attendance
|
||||||
|
|
||||||
|
import android.content.res.ColorStateList
|
||||||
import android.graphics.Typeface
|
import android.graphics.Typeface
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
@ -33,17 +34,17 @@ class AttendanceAdapter @Inject constructor() :
|
|||||||
)
|
)
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
|
||||||
|
val context = holder.binding.root.context
|
||||||
val item = items[position]
|
val item = items[position]
|
||||||
|
|
||||||
with(holder.binding) {
|
with(holder.binding) {
|
||||||
attendanceItemNumber.text = item.number.toString()
|
attendanceItemNumber.text = item.number.toString()
|
||||||
attendanceItemSubject.text = item.subject.ifBlank {
|
attendanceItemSubject.text = item.subject
|
||||||
root.context.getString(R.string.all_no_data)
|
.ifBlank { context.getString(R.string.all_no_data) }
|
||||||
}
|
|
||||||
attendanceItemDescription.setText(item.descriptionRes)
|
attendanceItemDescription.setText(item.descriptionRes)
|
||||||
|
|
||||||
attendanceItemDescription.setTextColor(
|
attendanceItemDescription.setTextColor(
|
||||||
root.context.getThemeAttrColor(
|
context.getThemeAttrColor(
|
||||||
when {
|
when {
|
||||||
item.absence && !item.excused -> R.attr.colorAttendanceAbsence
|
item.absence && !item.excused -> R.attr.colorAttendanceAbsence
|
||||||
item.lateness && !item.excused -> R.attr.colorAttendanceLateness
|
item.lateness && !item.excused -> R.attr.colorAttendanceLateness
|
||||||
@ -61,13 +62,15 @@ class AttendanceAdapter @Inject constructor() :
|
|||||||
attendanceItemAlert.isVisible =
|
attendanceItemAlert.isVisible =
|
||||||
item.let { (it.absence && !it.excused) || (it.lateness && !it.excused) }
|
item.let { (it.absence && !it.excused) || (it.lateness && !it.excused) }
|
||||||
|
|
||||||
attendanceItemAlert.setColorFilter(root.context.getThemeAttrColor(
|
attendanceItemAlert.imageTintList = ColorStateList.valueOf(
|
||||||
when{
|
context.getThemeAttrColor(
|
||||||
|
when {
|
||||||
item.absence && !item.excused -> R.attr.colorAttendanceAbsence
|
item.absence && !item.excused -> R.attr.colorAttendanceAbsence
|
||||||
item.lateness && !item.excused -> R.attr.colorAttendanceLateness
|
item.lateness && !item.excused -> R.attr.colorAttendanceLateness
|
||||||
else -> android.R.attr.colorPrimary
|
else -> android.R.attr.colorPrimary
|
||||||
}
|
}
|
||||||
))
|
)
|
||||||
|
)
|
||||||
attendanceItemNumber.visibility = View.GONE
|
attendanceItemNumber.visibility = View.GONE
|
||||||
attendanceItemExcuseInfo.visibility = View.GONE
|
attendanceItemExcuseInfo.visibility = View.GONE
|
||||||
attendanceItemExcuseCheckbox.visibility = View.GONE
|
attendanceItemExcuseCheckbox.visibility = View.GONE
|
||||||
|
@ -78,4 +78,9 @@ class AuthDialog : BaseDialogFragment<DialogAuthBinding>(), AuthView {
|
|||||||
override fun showDescriptionWithName(name: String) {
|
override fun showDescriptionWithName(name: String) {
|
||||||
binding.authDescription.text = getString(R.string.auth_description, name).parseAsHtml()
|
binding.authDescription.text = getString(R.string.auth_description, name).parseAsHtml()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onDestroyView() {
|
||||||
|
presenter.onDetachView()
|
||||||
|
super.onDestroyView()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,6 +73,7 @@ class MainPresenter @Inject constructor(
|
|||||||
syncManager.startPeriodicSyncWorker()
|
syncManager.startPeriodicSyncWorker()
|
||||||
|
|
||||||
checkAppSupport()
|
checkAppSupport()
|
||||||
|
checkCurrentStudentAuthorizationStatus()
|
||||||
|
|
||||||
analytics.logEvent("app_open", "destination" to initDestination.toString())
|
analytics.logEvent("app_open", "destination" to initDestination.toString())
|
||||||
Timber.i("Main view was initialized with $initDestination")
|
Timber.i("Main view was initialized with $initDestination")
|
||||||
@ -191,4 +192,13 @@ class MainPresenter @Inject constructor(
|
|||||||
|
|
||||||
view?.showStudentAvatar(currentStudent)
|
view?.showStudentAvatar(currentStudent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun checkCurrentStudentAuthorizationStatus() {
|
||||||
|
presenterScope.launch {
|
||||||
|
runCatching { studentRepository.checkCurrentStudentAuthorizationStatus() }
|
||||||
|
.onFailure { errorHandler.dispatch(it) }
|
||||||
|
|
||||||
|
Timber.i("Current student authorization status checked")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,6 @@ class MailboxChooserDialog : BaseDialogFragment<DialogMailboxChooserBinding>(),
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
presenter.onAttachView(
|
presenter.onAttachView(
|
||||||
|
@ -82,10 +82,10 @@ class MessagePreviewFragment :
|
|||||||
get() = getString(R.string.message_not_exists)
|
get() = getString(R.string.message_not_exists)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val MESSAGE_ID_KEY = "message_id"
|
private const val MESSAGE_ARG_KEY = "message"
|
||||||
|
|
||||||
fun newInstance(message: Message) = MessagePreviewFragment().apply {
|
fun newInstance(message: Message) = MessagePreviewFragment().apply {
|
||||||
arguments = bundleOf(MESSAGE_ID_KEY to message)
|
arguments = bundleOf(MESSAGE_ARG_KEY to message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,7 +101,7 @@ class MessagePreviewFragment :
|
|||||||
messageContainer = binding.messagePreviewContainer
|
messageContainer = binding.messagePreviewContainer
|
||||||
presenter.onAttachView(
|
presenter.onAttachView(
|
||||||
view = this,
|
view = this,
|
||||||
message = (savedInstanceState ?: arguments)?.serializable(MESSAGE_ID_KEY),
|
message = requireArguments().serializable(MESSAGE_ARG_KEY),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,11 +233,6 @@ class MessagePreviewFragment :
|
|||||||
(activity as MainActivity).popView()
|
(activity as MainActivity).popView()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSaveInstanceState(outState: Bundle) {
|
|
||||||
outState.putSerializable(MESSAGE_ID_KEY, presenter.messageWithAttachments?.message)
|
|
||||||
super.onSaveInstanceState(outState)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
presenter.onDetachView()
|
presenter.onDetachView()
|
||||||
super.onDestroyView()
|
super.onDestroyView()
|
||||||
|
@ -3,10 +3,15 @@ package io.github.wulkanowy.ui.modules.message.preview
|
|||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import androidx.core.text.parseAsHtml
|
import androidx.core.text.parseAsHtml
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.data.*
|
|
||||||
import io.github.wulkanowy.data.db.entities.Message
|
import io.github.wulkanowy.data.db.entities.Message
|
||||||
import io.github.wulkanowy.data.db.entities.MessageWithAttachment
|
import io.github.wulkanowy.data.db.entities.MessageWithAttachment
|
||||||
import io.github.wulkanowy.data.enums.MessageFolder
|
import io.github.wulkanowy.data.enums.MessageFolder
|
||||||
|
import io.github.wulkanowy.data.flatResourceFlow
|
||||||
|
import io.github.wulkanowy.data.logResourceStatus
|
||||||
|
import io.github.wulkanowy.data.onResourceData
|
||||||
|
import io.github.wulkanowy.data.onResourceError
|
||||||
|
import io.github.wulkanowy.data.onResourceNotLoading
|
||||||
|
import io.github.wulkanowy.data.onResourceSuccess
|
||||||
import io.github.wulkanowy.data.repositories.MessageRepository
|
import io.github.wulkanowy.data.repositories.MessageRepository
|
||||||
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||||
@ -28,17 +33,17 @@ class MessagePreviewPresenter @Inject constructor(
|
|||||||
private val analytics: AnalyticsHelper
|
private val analytics: AnalyticsHelper
|
||||||
) : BasePresenter<MessagePreviewView>(errorHandler, studentRepository) {
|
) : BasePresenter<MessagePreviewView>(errorHandler, studentRepository) {
|
||||||
|
|
||||||
var messageWithAttachments: MessageWithAttachment? = null
|
private var messageWithAttachments: MessageWithAttachment? = null
|
||||||
|
|
||||||
private lateinit var lastError: Throwable
|
private lateinit var lastError: Throwable
|
||||||
|
|
||||||
private var retryCallback: () -> Unit = {}
|
private var retryCallback: () -> Unit = {}
|
||||||
|
|
||||||
fun onAttachView(view: MessagePreviewView, message: Message?) {
|
fun onAttachView(view: MessagePreviewView, message: Message) {
|
||||||
super.onAttachView(view)
|
super.onAttachView(view)
|
||||||
view.initView()
|
view.initView()
|
||||||
errorHandler.showErrorMessage = ::showErrorViewOnError
|
errorHandler.showErrorMessage = ::showErrorViewOnError
|
||||||
loadData(requireNotNull(message))
|
loadData(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onMessageLoadRetry(message: Message) {
|
private fun onMessageLoadRetry(message: Message) {
|
||||||
|
@ -4,30 +4,31 @@ import android.content.Intent
|
|||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
|
import androidx.core.os.BundleCompat
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
|
|
||||||
|
// Even though API was introduced in 33, we use 34 as 33 is bugged in some scenarios.
|
||||||
|
|
||||||
inline fun <reified T : Serializable> Bundle.serializable(key: String): T = when {
|
inline fun <reified T : Serializable> Bundle.serializable(key: String): T = when {
|
||||||
Build.VERSION.SDK_INT >= 33 -> getSerializable(key, T::class.java)!!
|
Build.VERSION.SDK_INT >= 34 -> getSerializable(key, T::class.java)!!
|
||||||
else -> @Suppress("DEPRECATION") getSerializable(key) as T
|
else -> @Suppress("DEPRECATION") getSerializable(key) as T
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <reified T : Serializable> Bundle.nullableSerializable(key: String): T? = when {
|
inline fun <reified T : Serializable> Bundle.nullableSerializable(key: String): T? = when {
|
||||||
Build.VERSION.SDK_INT >= 33 -> getSerializable(key, T::class.java)
|
Build.VERSION.SDK_INT >= 34 -> getSerializable(key, T::class.java)
|
||||||
else -> @Suppress("DEPRECATION") getSerializable(key) as T?
|
else -> @Suppress("DEPRECATION") getSerializable(key) as T?
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
inline fun <reified T : Parcelable> Bundle.parcelableArray(key: String): Array<T>? = when {
|
inline fun <reified T : Parcelable> Bundle.parcelableArray(key: String): Array<T>? =
|
||||||
Build.VERSION.SDK_INT >= 33 -> getParcelableArray(key, T::class.java)
|
BundleCompat.getParcelableArray(this, key, T::class.java) as Array<T>?
|
||||||
else -> @Suppress("DEPRECATION") getParcelableArray(key) as Array<T>?
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fun <reified T : Serializable> Intent.serializable(key: String): T = when {
|
inline fun <reified T : Serializable> Intent.serializable(key: String): T = when {
|
||||||
Build.VERSION.SDK_INT >= 33 -> getSerializableExtra(key, T::class.java)!!
|
Build.VERSION.SDK_INT >= 34 -> getSerializableExtra(key, T::class.java)!!
|
||||||
else -> @Suppress("DEPRECATION") getSerializableExtra(key) as T
|
else -> @Suppress("DEPRECATION") getSerializableExtra(key) as T
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <reified T : Serializable> Intent.nullableSerializable(key: String): T? = when {
|
inline fun <reified T : Serializable> Intent.nullableSerializable(key: String): T? = when {
|
||||||
Build.VERSION.SDK_INT >= 33 -> getSerializableExtra(key, T::class.java)
|
Build.VERSION.SDK_INT >= 34 -> getSerializableExtra(key, T::class.java)
|
||||||
else -> @Suppress("DEPRECATION") getSerializableExtra(key) as T?
|
else -> @Suppress("DEPRECATION") getSerializableExtra(key) as T?
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ fun Sdk.init(student: Student): Sdk {
|
|||||||
schoolSymbol = student.schoolSymbol
|
schoolSymbol = student.schoolSymbol
|
||||||
studentId = student.studentId
|
studentId = student.studentId
|
||||||
classId = student.classId
|
classId = student.classId
|
||||||
|
isEduOne = student.isEduOne
|
||||||
emptyCookieJarInterceptor = true
|
emptyCookieJarInterceptor = true
|
||||||
|
|
||||||
if (Sdk.Mode.valueOf(student.loginMode) == Sdk.Mode.HEBE) {
|
if (Sdk.Mode.valueOf(student.loginMode) == Sdk.Mode.HEBE) {
|
||||||
|
@ -1,11 +1,7 @@
|
|||||||
Wersja 2.5.1
|
Wersja 2.5.2
|
||||||
|
|
||||||
— dodaliśmy wyświetlanie ogłoszeń
|
— naprawiliśmy omyłkowe wyświetlanie ekranu z wymaganą autoryzacją numerem PESEL
|
||||||
— dodaliśmy opcję przywracania wiadomości z kosza
|
— naprawiliśmy kilka problemów ze stabilnością
|
||||||
— dodaliśmy opcję wyciszania nadawców wiadomości
|
— poprawiliśmy wyświetlanie kolorów we frekwencji
|
||||||
— naprawiliśmy opcjonalne liczenie średniej arytmetycznej, kiedy brak ocen z wagą w drugim semestrze
|
|
||||||
— usprawniliśmy ładowanie frekwencji i planu lekcji
|
|
||||||
— naprawiliśmy usprawiedliwianie nieobecności i autoryzację u użytkowników eduOne
|
|
||||||
— zmieniliśmy komunikat o zmienionym haśle
|
|
||||||
|
|
||||||
Pełna lista zmian: https://github.com/wulkanowy/wulkanowy/releases
|
Pełna lista zmian: https://github.com/wulkanowy/wulkanowy/releases
|
||||||
|
@ -46,14 +46,15 @@
|
|||||||
|
|
||||||
<color name="timetable_canceled_light">#d32f2f</color>
|
<color name="timetable_canceled_light">#d32f2f</color>
|
||||||
<color name="timetable_canceled_dark">#e57373</color>
|
<color name="timetable_canceled_dark">#e57373</color>
|
||||||
|
|
||||||
<color name="timetable_change_light">#ff8f00</color>
|
<color name="timetable_change_light">#ff8f00</color>
|
||||||
<color name="timetable_change_dark">#ffd54f</color>
|
<color name="timetable_change_dark">#ffd54f</color>
|
||||||
|
|
||||||
<color name="attendance_absence_light">#d32f2f</color>
|
<color name="attendance_absence_light">#d32f2f</color>
|
||||||
<color name="attendance_absence_dark">#e57373</color>
|
<color name="attendance_absence_dark">#e57373</color>
|
||||||
|
|
||||||
<color name="attendance_lateness_light">#cd2a01</color>
|
<color name="attendance_lateness_light">#ff8f00</color>
|
||||||
<color name="attendance_lateness_dark">#f05d0e</color>
|
<color name="attendance_lateness_dark">#ffd54f</color>
|
||||||
|
|
||||||
<color name="colorDivider">#1f000000</color>
|
<color name="colorDivider">#1f000000</color>
|
||||||
<color name="colorDividerInverse">#1fffffff</color>
|
<color name="colorDividerInverse">#1fffffff</color>
|
||||||
|
@ -5,8 +5,8 @@ import io.github.wulkanowy.data.db.entities.MailboxType
|
|||||||
import io.github.wulkanowy.data.db.entities.Semester
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
import java.time.LocalDate
|
|
||||||
import java.time.Instant.now
|
import java.time.Instant.now
|
||||||
|
import java.time.LocalDate
|
||||||
import io.github.wulkanowy.sdk.pojo.Semester as SdkSemester
|
import io.github.wulkanowy.sdk.pojo.Semester as SdkSemester
|
||||||
|
|
||||||
fun getSemesterEntity(diaryId: Int = 1, semesterId: Int = 1, start: LocalDate = LocalDate.now(), end: LocalDate = LocalDate.now(), semesterName: Int = 1) = Semester(
|
fun getSemesterEntity(diaryId: Int = 1, semesterId: Int = 1, start: LocalDate = LocalDate.now(), end: LocalDate = LocalDate.now(), semesterName: Int = 1) = Semester(
|
||||||
@ -72,6 +72,8 @@ fun getStudentEntity(mode: Sdk.Mode = Sdk.Mode.HEBE) = Student(
|
|||||||
symbol = "",
|
symbol = "",
|
||||||
userLoginId = 1,
|
userLoginId = 1,
|
||||||
userName = "",
|
userName = "",
|
||||||
|
isEduOne = false,
|
||||||
|
isAuthorized = false
|
||||||
).apply {
|
).apply {
|
||||||
id = 1
|
id = 1
|
||||||
}
|
}
|
||||||
|
@ -222,5 +222,7 @@ class GetMailboxByStudentUseCaseTest {
|
|||||||
symbol = "",
|
symbol = "",
|
||||||
userLoginId = 1,
|
userLoginId = 1,
|
||||||
userName = userName,
|
userName = userName,
|
||||||
|
isAuthorized = false,
|
||||||
|
isEduOne = false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,9 @@ class GradeAverageProviderTest {
|
|||||||
className = "",
|
className = "",
|
||||||
classId = 1,
|
classId = 1,
|
||||||
isCurrent = true,
|
isCurrent = true,
|
||||||
registrationDate = Instant.now()
|
registrationDate = Instant.now(),
|
||||||
|
isAuthorized = false,
|
||||||
|
isEduOne = false
|
||||||
)
|
)
|
||||||
|
|
||||||
private val semesters = mutableListOf(
|
private val semesters = mutableListOf(
|
||||||
|
@ -71,6 +71,8 @@ class LoginStudentSelectPresenterTest {
|
|||||||
classId = 0,
|
classId = 0,
|
||||||
isParent = false,
|
isParent = false,
|
||||||
semesters = listOf(),
|
semesters = listOf(),
|
||||||
|
isEduOne = false,
|
||||||
|
isAuthorized = false,
|
||||||
)
|
)
|
||||||
|
|
||||||
private val school = RegisterUnit(
|
private val school = RegisterUnit(
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package io.github.wulkanowy.ui.modules.main
|
package io.github.wulkanowy.ui.modules.main
|
||||||
|
|
||||||
|
import io.github.wulkanowy.MainCoroutineRule
|
||||||
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||||
import io.github.wulkanowy.services.sync.SyncManager
|
import io.github.wulkanowy.services.sync.SyncManager
|
||||||
@ -7,14 +8,23 @@ import io.github.wulkanowy.ui.base.ErrorHandler
|
|||||||
import io.github.wulkanowy.utils.AdsHelper
|
import io.github.wulkanowy.utils.AdsHelper
|
||||||
import io.github.wulkanowy.utils.AnalyticsHelper
|
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||||
import io.github.wulkanowy.utils.AppInfo
|
import io.github.wulkanowy.utils.AppInfo
|
||||||
import io.mockk.*
|
import io.mockk.MockKAnnotations
|
||||||
|
import io.mockk.Runs
|
||||||
|
import io.mockk.clearMocks
|
||||||
|
import io.mockk.every
|
||||||
import io.mockk.impl.annotations.MockK
|
import io.mockk.impl.annotations.MockK
|
||||||
|
import io.mockk.just
|
||||||
|
import io.mockk.verify
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
class MainPresenterTest {
|
class MainPresenterTest {
|
||||||
|
|
||||||
|
@get:Rule
|
||||||
|
val coroutineRule = MainCoroutineRule()
|
||||||
|
|
||||||
@MockK(relaxed = true)
|
@MockK(relaxed = true)
|
||||||
lateinit var errorHandler: ErrorHandler
|
lateinit var errorHandler: ErrorHandler
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user