Compare commits
14 Commits
Author | SHA1 | Date | |
---|---|---|---|
b5cc32d59f | |||
d943d03266 | |||
6eca8c42f5 | |||
af989ba9f6 | |||
4a65a5b192 | |||
bbbafdfe70 | |||
a82e11d694 | |||
4dc5fc65ac | |||
7463cf6253 | |||
d799ec7ac9 | |||
254719f22f | |||
e1e276e1ea | |||
8cdd4311a9 | |||
b7f7b16aef |
@ -27,8 +27,8 @@ android {
|
|||||||
testApplicationId "io.github.tests.wulkanowy"
|
testApplicationId "io.github.tests.wulkanowy"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 34
|
targetSdkVersion 34
|
||||||
versionCode 152
|
versionCode 155
|
||||||
versionName "2.5.3"
|
versionName "2.5.6"
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
|
||||||
resValue "string", "app_name", "Wulkanowy"
|
resValue "string", "app_name", "Wulkanowy"
|
||||||
@ -164,7 +164,7 @@ play {
|
|||||||
defaultToAppBundles = false
|
defaultToAppBundles = false
|
||||||
track = 'production'
|
track = 'production'
|
||||||
releaseStatus = ReleaseStatus.IN_PROGRESS
|
releaseStatus = ReleaseStatus.IN_PROGRESS
|
||||||
userFraction = 0.20d
|
userFraction = 0.99d
|
||||||
updatePriority = 3
|
updatePriority = 3
|
||||||
enabled.set(false)
|
enabled.set(false)
|
||||||
}
|
}
|
||||||
@ -195,7 +195,7 @@ ext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'io.github.wulkanowy:sdk:2.5.3'
|
implementation 'io.github.wulkanowy:sdk:2.5.6'
|
||||||
|
|
||||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4'
|
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4'
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ class WulkanowySdkFactory @Inject constructor(
|
|||||||
) {
|
) {
|
||||||
|
|
||||||
private val eduOneMutex = Mutex()
|
private val eduOneMutex = Mutex()
|
||||||
|
private val migrationFailedStudentIds = mutableSetOf<Long>()
|
||||||
|
|
||||||
private val sdk = Sdk().apply {
|
private val sdk = Sdk().apply {
|
||||||
androidVersion = android.os.Build.VERSION.RELEASE
|
androidVersion = android.os.Build.VERSION.RELEASE
|
||||||
@ -78,14 +79,24 @@ class WulkanowySdkFactory @Inject constructor(
|
|||||||
private suspend fun checkEduOneAndMigrateIfNecessary(student: Student): Boolean {
|
private suspend fun checkEduOneAndMigrateIfNecessary(student: Student): Boolean {
|
||||||
if (student.isEduOne != null) return student.isEduOne
|
if (student.isEduOne != null) return student.isEduOne
|
||||||
|
|
||||||
|
if (student.id in migrationFailedStudentIds) {
|
||||||
|
Timber.i("Migration eduOne: skipping because of previous failure")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
eduOneMutex.withLock {
|
eduOneMutex.withLock {
|
||||||
|
if (student.id in migrationFailedStudentIds) {
|
||||||
|
Timber.i("Migration eduOne: skipping because of previous failure")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
val studentFromDatabase = studentDb.loadById(student.id)
|
val studentFromDatabase = studentDb.loadById(student.id)
|
||||||
if (studentFromDatabase?.isEduOne != null) {
|
if (studentFromDatabase?.isEduOne != null) {
|
||||||
Timber.d("Migration eduOne: already done")
|
Timber.i("Migration eduOne: already done")
|
||||||
return studentFromDatabase.isEduOne
|
return studentFromDatabase.isEduOne
|
||||||
}
|
}
|
||||||
|
|
||||||
Timber.d("Migration eduOne: flag missing. Running migration...")
|
Timber.i("Migration eduOne: flag missing. Running migration...")
|
||||||
val initializedSdk = buildSdk(
|
val initializedSdk = buildSdk(
|
||||||
student = student,
|
student = student,
|
||||||
semester = null,
|
semester = null,
|
||||||
@ -96,11 +107,12 @@ class WulkanowySdkFactory @Inject constructor(
|
|||||||
.getOrNull()
|
.getOrNull()
|
||||||
|
|
||||||
if (newCurrentStudent == null) {
|
if (newCurrentStudent == null) {
|
||||||
Timber.d("Migration eduOne: failed, so skipping")
|
Timber.i("Migration eduOne: failed, so skipping")
|
||||||
|
migrationFailedStudentIds.add(student.id)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
Timber.d("Migration eduOne: success. New isEduOne flag: ${newCurrentStudent.isEduOne}")
|
Timber.i("Migration eduOne: success. New isEduOne flag: ${newCurrentStudent.isEduOne}")
|
||||||
|
|
||||||
val studentIsEduOne = StudentIsEduOne(
|
val studentIsEduOne = StudentIsEduOne(
|
||||||
id = student.id,
|
id = student.id,
|
||||||
|
@ -8,6 +8,6 @@ import kotlinx.coroutines.flow.Flow
|
|||||||
@Dao
|
@Dao
|
||||||
interface MobileDeviceDao : BaseDao<MobileDevice> {
|
interface MobileDeviceDao : BaseDao<MobileDevice> {
|
||||||
|
|
||||||
@Query("SELECT * FROM MobileDevices WHERE user_login_id = :userLoginId ORDER BY date DESC")
|
@Query("SELECT * FROM MobileDevices WHERE user_login_id = :studentId ORDER BY date DESC")
|
||||||
fun loadAll(userLoginId: Int): Flow<List<MobileDevice>>
|
fun loadAll(studentId: Int): Flow<List<MobileDevice>>
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,6 @@ import javax.inject.Singleton
|
|||||||
@Singleton
|
@Singleton
|
||||||
interface SchoolAnnouncementDao : BaseDao<SchoolAnnouncement> {
|
interface SchoolAnnouncementDao : BaseDao<SchoolAnnouncement> {
|
||||||
|
|
||||||
@Query("SELECT * FROM SchoolAnnouncements WHERE user_login_id = :userLoginId ORDER BY date DESC")
|
@Query("SELECT * FROM SchoolAnnouncements WHERE user_login_id = :studentId ORDER BY date DESC")
|
||||||
fun loadAll(userLoginId: Int): Flow<List<SchoolAnnouncement>>
|
fun loadAll(studentId: Int): Flow<List<SchoolAnnouncement>>
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,6 @@ interface SemesterDao : BaseDao<Semester> {
|
|||||||
@Insert(onConflict = OnConflictStrategy.IGNORE)
|
@Insert(onConflict = OnConflictStrategy.IGNORE)
|
||||||
suspend fun insertSemesters(items: List<Semester>): List<Long>
|
suspend fun insertSemesters(items: List<Semester>): List<Long>
|
||||||
|
|
||||||
@Query("SELECT * FROM Semesters WHERE student_id = :studentId AND class_id = :classId")
|
@Query("SELECT * FROM Semesters WHERE (student_id = :studentId AND class_id = :classId) OR (student_id = :studentId AND class_id = 0)")
|
||||||
suspend fun loadAll(studentId: Int, classId: Int): List<Semester>
|
suspend fun loadAll(studentId: Int, classId: Int): List<Semester>
|
||||||
}
|
}
|
||||||
|
@ -47,11 +47,11 @@ abstract class StudentDao {
|
|||||||
abstract suspend fun loadAll(): List<Student>
|
abstract suspend fun loadAll(): List<Student>
|
||||||
|
|
||||||
@Transaction
|
@Transaction
|
||||||
@Query("SELECT * FROM Students JOIN Semesters ON Students.student_id = Semesters.student_id AND Students.class_id = Semesters.class_id")
|
@Query("SELECT * FROM Students JOIN Semesters ON (Students.student_id = Semesters.student_id AND Students.class_id = Semesters.class_id) OR (Students.student_id = Semesters.student_id AND Semesters.class_id = 0)")
|
||||||
abstract suspend fun loadStudentsWithSemesters(): Map<Student, List<Semester>>
|
abstract suspend fun loadStudentsWithSemesters(): Map<Student, List<Semester>>
|
||||||
|
|
||||||
@Transaction
|
@Transaction
|
||||||
@Query("SELECT * FROM Students JOIN Semesters ON Students.student_id = Semesters.student_id AND Students.class_id = Semesters.class_id WHERE Students.id = :id")
|
@Query("SELECT * FROM Students JOIN Semesters ON (Students.student_id = Semesters.student_id AND Students.class_id = Semesters.class_id) OR (Students.student_id = Semesters.student_id AND Semesters.class_id = 0) WHERE Students.id = :id")
|
||||||
abstract suspend fun loadStudentWithSemestersById(id: Long): Map<Student, List<Semester>>
|
abstract suspend fun loadStudentWithSemestersById(id: Long): Map<Student, List<Semester>>
|
||||||
|
|
||||||
@Query("UPDATE Students SET is_current = 1 WHERE id = :id")
|
@Query("UPDATE Students SET is_current = 1 WHERE id = :id")
|
||||||
|
@ -9,8 +9,8 @@ import java.time.Instant
|
|||||||
@Entity(tableName = "MobileDevices")
|
@Entity(tableName = "MobileDevices")
|
||||||
data class MobileDevice(
|
data class MobileDevice(
|
||||||
|
|
||||||
@ColumnInfo(name = "user_login_id")
|
@ColumnInfo(name = "user_login_id") // todo: change column name
|
||||||
val userLoginId: Int,
|
val studentId: Int,
|
||||||
|
|
||||||
@ColumnInfo(name = "device_id")
|
@ColumnInfo(name = "device_id")
|
||||||
val deviceId: Int,
|
val deviceId: Int,
|
||||||
|
@ -9,8 +9,8 @@ import java.time.LocalDate
|
|||||||
@Entity(tableName = "SchoolAnnouncements")
|
@Entity(tableName = "SchoolAnnouncements")
|
||||||
data class SchoolAnnouncement(
|
data class SchoolAnnouncement(
|
||||||
|
|
||||||
@ColumnInfo(name = "user_login_id")
|
@ColumnInfo(name = "user_login_id") // todo: change column name
|
||||||
val userLoginId: Int,
|
val studentId: Int,
|
||||||
|
|
||||||
val date: LocalDate,
|
val date: LocalDate,
|
||||||
|
|
||||||
|
@ -49,6 +49,7 @@ data class Student(
|
|||||||
@ColumnInfo(name = "student_id")
|
@ColumnInfo(name = "student_id")
|
||||||
val studentId: Int,
|
val studentId: Int,
|
||||||
|
|
||||||
|
@Deprecated("not available in VULCAN anymore")
|
||||||
@ColumnInfo(name = "user_login_id")
|
@ColumnInfo(name = "user_login_id")
|
||||||
val userLoginId: Int,
|
val userLoginId: Int,
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ import io.github.wulkanowy.sdk.pojo.LastAnnouncement as SdkLastAnnouncement
|
|||||||
@JvmName("mapDirectorInformationToEntities")
|
@JvmName("mapDirectorInformationToEntities")
|
||||||
fun List<SdkDirectorInformation>.mapToEntities(student: Student) = map {
|
fun List<SdkDirectorInformation>.mapToEntities(student: Student) = map {
|
||||||
SchoolAnnouncement(
|
SchoolAnnouncement(
|
||||||
userLoginId = student.userLoginId,
|
studentId = student.studentId,
|
||||||
date = it.date,
|
date = it.date,
|
||||||
subject = it.subject,
|
subject = it.subject,
|
||||||
content = it.content,
|
content = it.content,
|
||||||
@ -19,7 +19,7 @@ fun List<SdkDirectorInformation>.mapToEntities(student: Student) = map {
|
|||||||
@JvmName("mapLastAnnouncementsToEntities")
|
@JvmName("mapLastAnnouncementsToEntities")
|
||||||
fun List<SdkLastAnnouncement>.mapToEntities(student: Student) = map {
|
fun List<SdkLastAnnouncement>.mapToEntities(student: Student) = map {
|
||||||
SchoolAnnouncement(
|
SchoolAnnouncement(
|
||||||
userLoginId = student.userLoginId,
|
studentId = student.studentId,
|
||||||
date = it.date,
|
date = it.date,
|
||||||
subject = it.subject,
|
subject = it.subject,
|
||||||
content = it.content,
|
content = it.content,
|
||||||
|
@ -8,7 +8,7 @@ import io.github.wulkanowy.sdk.pojo.Token as SdkToken
|
|||||||
|
|
||||||
fun List<SdkDevice>.mapToEntities(student: Student) = map {
|
fun List<SdkDevice>.mapToEntities(student: Student) = map {
|
||||||
MobileDevice(
|
MobileDevice(
|
||||||
userLoginId = student.userLoginId,
|
studentId = student.studentId,
|
||||||
date = it.createDate.toInstant(),
|
date = it.createDate.toInstant(),
|
||||||
deviceId = it.id,
|
deviceId = it.id,
|
||||||
name = it.name
|
name = it.name
|
||||||
|
@ -38,7 +38,7 @@ class MobileDeviceRepository @Inject constructor(
|
|||||||
val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(cacheKey, student))
|
val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(cacheKey, student))
|
||||||
it.isEmpty() || forceRefresh || isExpired
|
it.isEmpty() || forceRefresh || isExpired
|
||||||
},
|
},
|
||||||
query = { mobileDb.loadAll(student.userLoginId) },
|
query = { mobileDb.loadAll(student.studentId) },
|
||||||
fetch = {
|
fetch = {
|
||||||
wulkanowySdkFactory.create(student, semester)
|
wulkanowySdkFactory.create(student, semester)
|
||||||
.getRegisteredDevices()
|
.getRegisteredDevices()
|
||||||
|
@ -37,7 +37,7 @@ class SchoolAnnouncementRepository @Inject constructor(
|
|||||||
it.isEmpty() || forceRefresh || isExpired
|
it.isEmpty() || forceRefresh || isExpired
|
||||||
},
|
},
|
||||||
query = {
|
query = {
|
||||||
schoolAnnouncementDb.loadAll(student.userLoginId)
|
schoolAnnouncementDb.loadAll(student.studentId)
|
||||||
},
|
},
|
||||||
fetch = {
|
fetch = {
|
||||||
val sdk = wulkanowySdkFactory.create(student)
|
val sdk = wulkanowySdkFactory.create(student)
|
||||||
@ -57,7 +57,7 @@ class SchoolAnnouncementRepository @Inject constructor(
|
|||||||
)
|
)
|
||||||
|
|
||||||
fun getSchoolAnnouncementFromDatabase(student: Student): Flow<List<SchoolAnnouncement>> {
|
fun getSchoolAnnouncementFromDatabase(student: Student): Flow<List<SchoolAnnouncement>> {
|
||||||
return schoolAnnouncementDb.loadAll(student.userLoginId)
|
return schoolAnnouncementDb.loadAll(student.studentId)
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun updateSchoolAnnouncement(schoolAnnouncement: List<SchoolAnnouncement>) =
|
suspend fun updateSchoolAnnouncement(schoolAnnouncement: List<SchoolAnnouncement>) =
|
||||||
|
@ -64,7 +64,10 @@ class SemesterRepository @Inject constructor(
|
|||||||
.getSemesters()
|
.getSemesters()
|
||||||
.mapToEntities(student.studentId)
|
.mapToEntities(student.studentId)
|
||||||
|
|
||||||
if (new.isEmpty()) return Timber.i("Empty semester list!")
|
if (new.isEmpty()) {
|
||||||
|
Timber.i("Empty semester list from SDK!")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
val old = semesterDb.loadAll(student.studentId, student.classId)
|
val old = semesterDb.loadAll(student.studentId, student.classId)
|
||||||
semesterDb.removeOldAndSaveNew(
|
semesterDb.removeOldAndSaveNew(
|
||||||
|
@ -42,6 +42,7 @@ class StudentRepository @Inject constructor(
|
|||||||
): RegisterUser = wulkanowySdkFactory.create()
|
): RegisterUser = wulkanowySdkFactory.create()
|
||||||
.getStudentsFromHebe(token, pin, symbol, "")
|
.getStudentsFromHebe(token, pin, symbol, "")
|
||||||
.mapToPojo(null)
|
.mapToPojo(null)
|
||||||
|
.also { it.logErrors() }
|
||||||
|
|
||||||
suspend fun getUserSubjectsFromScrapper(
|
suspend fun getUserSubjectsFromScrapper(
|
||||||
email: String,
|
email: String,
|
||||||
@ -52,6 +53,7 @@ class StudentRepository @Inject constructor(
|
|||||||
): RegisterUser = wulkanowySdkFactory.create()
|
): RegisterUser = wulkanowySdkFactory.create()
|
||||||
.getUserSubjectsFromScrapper(email, password, scrapperBaseUrl, domainSuffix, symbol)
|
.getUserSubjectsFromScrapper(email, password, scrapperBaseUrl, domainSuffix, symbol)
|
||||||
.mapToPojo(password)
|
.mapToPojo(password)
|
||||||
|
.also { it.logErrors() }
|
||||||
|
|
||||||
suspend fun getStudentsHybrid(
|
suspend fun getStudentsHybrid(
|
||||||
email: String,
|
email: String,
|
||||||
@ -61,6 +63,7 @@ class StudentRepository @Inject constructor(
|
|||||||
): RegisterUser = wulkanowySdkFactory.create()
|
): RegisterUser = wulkanowySdkFactory.create()
|
||||||
.getStudentsHybrid(email, password, scrapperBaseUrl, "", symbol)
|
.getStudentsHybrid(email, password, scrapperBaseUrl, "", symbol)
|
||||||
.mapToPojo(password)
|
.mapToPojo(password)
|
||||||
|
.also { it.logErrors() }
|
||||||
|
|
||||||
suspend fun getSavedStudents(decryptPass: Boolean = true): List<StudentWithSemesters> {
|
suspend fun getSavedStudents(decryptPass: Boolean = true): List<StudentWithSemesters> {
|
||||||
return studentDb.loadStudentsWithSemesters().map { (student, semesters) ->
|
return studentDb.loadStudentsWithSemesters().map { (student, semesters) ->
|
||||||
@ -195,10 +198,10 @@ class StudentRepository @Inject constructor(
|
|||||||
.authorizePermission(pesel)
|
.authorizePermission(pesel)
|
||||||
|
|
||||||
suspend fun refreshStudentAfterAuthorize(student: Student, semester: Semester) {
|
suspend fun refreshStudentAfterAuthorize(student: Student, semester: Semester) {
|
||||||
val newCurrentApiStudent = wulkanowySdkFactory
|
val wulkanowySdk = wulkanowySdkFactory.create(student, semester)
|
||||||
.create(student, semester)
|
val newCurrentApiStudent = runCatching { wulkanowySdk.getCurrentStudent() }
|
||||||
.getCurrentStudent()
|
.onFailure { Timber.e(it, "Can't find student with id ${student.studentId}") }
|
||||||
?: return Timber.d("Can't find student with id ${student.studentId}")
|
.getOrNull() ?: return
|
||||||
|
|
||||||
val studentName = StudentName(
|
val studentName = StudentName(
|
||||||
studentName = "${newCurrentApiStudent.studentName} ${newCurrentApiStudent.studentSurname}"
|
studentName = "${newCurrentApiStudent.studentName} ${newCurrentApiStudent.studentSurname}"
|
||||||
@ -221,6 +224,18 @@ class StudentRepository @Inject constructor(
|
|||||||
appDatabase.clearAllTables()
|
appDatabase.clearAllTables()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun RegisterUser.logErrors() {
|
||||||
|
val symbolsErrors = symbols.filter { it.error != null }
|
||||||
|
.map { it.error }
|
||||||
|
val unitsErrors = symbols.flatMap { it.schools }
|
||||||
|
.filter { it.error != null }
|
||||||
|
.map { it.error }
|
||||||
|
|
||||||
|
(symbolsErrors + unitsErrors).forEach { error ->
|
||||||
|
Timber.e(error, "Error occurred while fetching students")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class NoAuthorizationException : Exception()
|
class NoAuthorizationException : Exception()
|
||||||
|
@ -19,6 +19,6 @@ val debugSchoolAnnouncementItems = listOf(
|
|||||||
private fun generateAnnouncement(subject: String, content: String) = SchoolAnnouncement(
|
private fun generateAnnouncement(subject: String, content: String) = SchoolAnnouncement(
|
||||||
subject = subject,
|
subject = subject,
|
||||||
content = content,
|
content = content,
|
||||||
userLoginId = 0,
|
studentId = 0,
|
||||||
date = LocalDate.now()
|
date = LocalDate.now()
|
||||||
)
|
)
|
||||||
|
@ -19,19 +19,23 @@ class LoginStudentSelectAdapter @Inject constructor() :
|
|||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||||
val inflater = LayoutInflater.from(parent.context)
|
val inflater = LayoutInflater.from(parent.context)
|
||||||
return when (LoginStudentSelectItemType.values()[viewType]) {
|
return when (LoginStudentSelectItemType.entries[viewType]) {
|
||||||
LoginStudentSelectItemType.EMPTY_SYMBOLS_HEADER -> EmptySymbolsHeaderViewHolder(
|
LoginStudentSelectItemType.EMPTY_SYMBOLS_HEADER -> EmptySymbolsHeaderViewHolder(
|
||||||
ItemLoginStudentSelectEmptySymbolHeaderBinding.inflate(inflater, parent, false),
|
ItemLoginStudentSelectEmptySymbolHeaderBinding.inflate(inflater, parent, false),
|
||||||
)
|
)
|
||||||
|
|
||||||
LoginStudentSelectItemType.SYMBOL_HEADER -> SymbolsHeaderViewHolder(
|
LoginStudentSelectItemType.SYMBOL_HEADER -> SymbolsHeaderViewHolder(
|
||||||
ItemLoginStudentSelectHeaderSymbolBinding.inflate(inflater, parent, false)
|
ItemLoginStudentSelectHeaderSymbolBinding.inflate(inflater, parent, false)
|
||||||
)
|
)
|
||||||
|
|
||||||
LoginStudentSelectItemType.SCHOOL_HEADER -> SchoolHeaderViewHolder(
|
LoginStudentSelectItemType.SCHOOL_HEADER -> SchoolHeaderViewHolder(
|
||||||
ItemLoginStudentSelectHeaderSchoolBinding.inflate(inflater, parent, false)
|
ItemLoginStudentSelectHeaderSchoolBinding.inflate(inflater, parent, false)
|
||||||
)
|
)
|
||||||
|
|
||||||
LoginStudentSelectItemType.STUDENT -> StudentViewHolder(
|
LoginStudentSelectItemType.STUDENT -> StudentViewHolder(
|
||||||
ItemLoginStudentSelectStudentBinding.inflate(inflater, parent, false)
|
ItemLoginStudentSelectStudentBinding.inflate(inflater, parent, false)
|
||||||
)
|
)
|
||||||
|
|
||||||
LoginStudentSelectItemType.HELP -> HelpViewHolder(
|
LoginStudentSelectItemType.HELP -> HelpViewHolder(
|
||||||
ItemLoginStudentSelectHelpBinding.inflate(inflater, parent, false)
|
ItemLoginStudentSelectHelpBinding.inflate(inflater, parent, false)
|
||||||
)
|
)
|
||||||
@ -98,9 +102,11 @@ class LoginStudentSelectAdapter @Inject constructor() :
|
|||||||
with(binding) {
|
with(binding) {
|
||||||
loginStudentSelectHeaderSchoolName.text = buildString {
|
loginStudentSelectHeaderSchoolName.text = buildString {
|
||||||
append(item.unit.schoolName.trim())
|
append(item.unit.schoolName.trim())
|
||||||
append(" (")
|
if (item.unit.schoolShortName.isNotBlank()) {
|
||||||
append(item.unit.schoolShortName)
|
append(" (")
|
||||||
append(")")
|
append(item.unit.schoolShortName)
|
||||||
|
append(")")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
loginStudentSelectHeaderSchoolDetails.isVisible = item.unit.students.isEmpty()
|
loginStudentSelectHeaderSchoolDetails.isVisible = item.unit.students.isEmpty()
|
||||||
loginStudentSelectHeaderSchoolError.text = item.unit.error?.message
|
loginStudentSelectHeaderSchoolError.text = item.unit.error?.message
|
||||||
@ -170,9 +176,11 @@ class LoginStudentSelectAdapter @Inject constructor() :
|
|||||||
oldItem is LoginStudentSelectItem.SymbolHeader && newItem is LoginStudentSelectItem.SymbolHeader -> {
|
oldItem is LoginStudentSelectItem.SymbolHeader && newItem is LoginStudentSelectItem.SymbolHeader -> {
|
||||||
oldItem.symbol == newItem.symbol
|
oldItem.symbol == newItem.symbol
|
||||||
}
|
}
|
||||||
|
|
||||||
oldItem is LoginStudentSelectItem.Student && newItem is LoginStudentSelectItem.Student -> {
|
oldItem is LoginStudentSelectItem.Student && newItem is LoginStudentSelectItem.Student -> {
|
||||||
oldItem.student == newItem.student
|
oldItem.student == newItem.student
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> oldItem == newItem
|
else -> oldItem == newItem
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ import io.github.wulkanowy.data.pojos.RegisterUser
|
|||||||
import io.github.wulkanowy.data.repositories.SchoolsRepository
|
import io.github.wulkanowy.data.repositories.SchoolsRepository
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||||
import io.github.wulkanowy.data.resourceFlow
|
import io.github.wulkanowy.data.resourceFlow
|
||||||
|
import io.github.wulkanowy.sdk.scrapper.exception.StudentGraduateException
|
||||||
import io.github.wulkanowy.sdk.scrapper.login.InvalidSymbolException
|
import io.github.wulkanowy.sdk.scrapper.login.InvalidSymbolException
|
||||||
import io.github.wulkanowy.services.sync.SyncManager
|
import io.github.wulkanowy.services.sync.SyncManager
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
@ -108,8 +109,8 @@ class LoginStudentSelectPresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun createItems(): List<LoginStudentSelectItem> = buildList {
|
private fun createItems(): List<LoginStudentSelectItem> = buildList {
|
||||||
val notEmptySymbols = registerUser.symbols.filter { it.schools.isNotEmpty() }
|
val notEmptySymbols = registerUser.symbols.filter { it.shouldShowOnTop() }
|
||||||
val emptySymbols = registerUser.symbols.filter { it.schools.isEmpty() }
|
val emptySymbols = registerUser.symbols.filter { !it.shouldShowOnTop() }
|
||||||
|
|
||||||
if (emptySymbols.isNotEmpty() && notEmptySymbols.isNotEmpty() && emptySymbols.any { it.symbol == loginData.userEnteredSymbol }) {
|
if (emptySymbols.isNotEmpty() && notEmptySymbols.isNotEmpty() && emptySymbols.any { it.symbol == loginData.userEnteredSymbol }) {
|
||||||
add(createEmptySymbolItem(emptySymbols.first { it.symbol == loginData.userEnteredSymbol }))
|
add(createEmptySymbolItem(emptySymbols.first { it.symbol == loginData.userEnteredSymbol }))
|
||||||
@ -127,6 +128,10 @@ class LoginStudentSelectPresenter @Inject constructor(
|
|||||||
add(helpItem)
|
add(helpItem)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun RegisterSymbol.shouldShowOnTop(): Boolean {
|
||||||
|
return schools.isNotEmpty() || error is StudentGraduateException
|
||||||
|
}
|
||||||
|
|
||||||
private fun createNotEmptySymbolItems(
|
private fun createNotEmptySymbolItems(
|
||||||
notEmptySymbols: List<RegisterSymbol>,
|
notEmptySymbols: List<RegisterSymbol>,
|
||||||
students: List<StudentWithSemesters>,
|
students: List<StudentWithSemesters>,
|
||||||
|
@ -23,7 +23,7 @@ fun getRefreshKey(name: String, semester: Semester): String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getRefreshKey(name: String, student: Student): String {
|
fun getRefreshKey(name: String, student: Student): String {
|
||||||
return "${name}_${student.userLoginId}"
|
return "${name}_${student.studentId}"
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getRefreshKey(name: String, mailbox: Mailbox?, folder: MessageFolder): String {
|
fun getRefreshKey(name: String, mailbox: Mailbox?, folder: MessageFolder): String {
|
||||||
|
@ -18,7 +18,7 @@ fun Semester.isCurrent(now: LocalDate = now()): Boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun List<Semester>.getCurrentOrLast(): Semester {
|
fun List<Semester>.getCurrentOrLast(): Semester {
|
||||||
if (isEmpty()) throw RuntimeException("Empty semester list")
|
if (isEmpty()) throw IllegalStateException("Empty semester list")
|
||||||
|
|
||||||
// when there is only one current semester
|
// when there is only one current semester
|
||||||
singleOrNull { it.isCurrent() }?.let { return it }
|
singleOrNull { it.isCurrent() }?.let { return it }
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
Wersja 2.5.3
|
Wersja 2.5.6
|
||||||
|
|
||||||
— naprawiliśmy wyświetlanie błędu "Brak uprawnień" po starcie aplikacji u użytkowników eduOne
|
— naprawiliśmy logowanie (pusta lista z wyborem uczniów), które zepsuło się po zmianach po stronie VULCANa
|
||||||
— naprawiliśmy obsługę autoryzacji u użytkowników eduOne
|
|
||||||
— ukryliśmy numery lekcji i oceny klasy u użytkowników eduOne, bo VULCAN te funkcje usunął
|
|
||||||
— naprawiliśmy inne rzeczy u użytkowników eduOne (jak brak opisu oceny czy ładowanie danych na kilku ekranach)
|
|
||||||
|
|
||||||
Pełna lista zmian: https://github.com/wulkanowy/wulkanowy/releases
|
Pełna lista zmian: https://github.com/wulkanowy/wulkanowy/releases
|
||||||
|
Reference in New Issue
Block a user